Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 仅从标准输入读取整数_C - Fatal编程技术网

C 仅从标准输入读取整数

C 仅从标准输入读取整数,c,C,我处理的是一个程序的一部分,它必须从stdin中读取行,如下所示: {1,7,22,4,7,5,11,9,1} 我必须只存储整数,以便程序以后使用它们 我想到的最原始的方法是在程序中放入while循环,如果 getchar()=='、'或getchar()=='}' 然后继续或结束读取,如果没有“,”或“}”,则读取int 你能想出更好的吗 不必麻烦getchar,您可以尝试scanf int d1,d2,d3; scanf( "{%d,%d,%d}", &d1, &d2, &a

我处理的是一个程序的一部分,它必须从
stdin
中读取行,如下所示:

{1,7,22,4,7,5,11,9,1}

我必须只存储整数,以便程序以后使用它们

我想到的最原始的方法是在程序中放入
while
循环,如果

getchar()=='、'或getchar()=='}'

然后继续或结束读取,如果没有“,”或“}”,则读取int


你能想出更好的吗

不必麻烦
getchar
,您可以尝试
scanf

int d1,d2,d3;
scanf( "{%d,%d,%d}", &d1, &d2, &d3);
printf( "d1 = %d, d2 = %d, d3 = %d\n", d1, d2, d3 );
如果您从
stdin
输入的是此格式的
{1,7,22}
,您将在
d1
d2
d3
中得到所需的内容


如果输入数量不固定,您可以尝试组合使用
fgets
strtok

char input_line[1000];
fgets( input_line, sizeof( input_line ), stdin );
char *pch = strtok (input_line,"{, \t}");
printf( "%d \n", atoi( pch ) );
while (pch != NULL)
{
    pch = strtok (NULL, "{, \t}");
    if( pch != NULL && pch[0] != '\n' )
    {
        printf( "%d \n", atoi( pch ) );
    }
}

如果输入是
{1,7,22,4,7,5,11,9,1}
,您将得到:

{ 1, 7, 22, 4, 7, 5, 11, 9, 1}      
1 
7 
22 
4 
7 
5 
11 
9 
1

我一直认为,编写一个通用的输入例程来处理数字输入,而不管其格式如何,比编写5个不同的例程来处理5种不同的格式更有意义。
strtol
是为处理字符串中包含的数字输入的转换而定制的,而不管其格式如何。宣言是:

long int strtol(const char *nptr, char **endptr, int base);
它以指针作为输入,并将
endptr
更新为在
nptr
中转换的数字后面的下一个字符,这一事实允许您从行首开始,一直工作到行尾,转换找到的每个数字,而不管输入的格式如何。这允许创建具有健壮错误检查的灵活输入解析函数

下面的一个简短示例将说明这种方法。默认情况下,该示例将从
stdin
读取,或者从作为第一个参数提供的任何文件名读取。
strtol
调用封装在一个简短的
xstrtol
函数中,该函数仅为每次转换提供正常的错误检查。将它放在函数中可以防止重复的错误检查使代码的主要逻辑混乱。例如:

#include <stdio.h>
#include <stdlib.h> /* for strtol   */
#include <limits.h> /* for INT_MIN/INT_MAX */
#include <errno.h>  /* for errno    */

#define MAXL 256

long xstrtol (char *p, char **ep, int base);

int main (int argc, char **argv)
{
    int values[MAXL] = {0};
    char line[MAXL] = {0};
    size_t i, idx = 0;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) { /* validate file open */
        fprintf (stderr, "error: file open failen '%s'.\n", argv[1]);
        return 1;
    }

    /* read each line in file (up to MAXL chars per-line) */
    while (fgets (line, MAXL, fp)) {

        char *p = line;
        char *ep = p;
        errno = 0;

        /* convert each string of digits into number */
        while (errno == 0) {

            /* skip any non-digit characters */
            while (*p && ((*p != '-' && (*p < '0' || *p > '9')) ||
                (*p == '-' && (*(p+1) < '0' || *(p+1) > '9')))) p++;
            if (!*p) break;

            /* convert string to number */
            values[idx++] = (int)xstrtol (p, &ep, 10);

            if (errno) break;   /* check for error */

            if (idx == MAXL) {  /* check if array full */
                fprintf (stderr, "warning: MAXL values read.\n");
                break;
            }

            /* skip delimiters/move pointer to next digit */
            while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
            if (*ep)
                p = ep;
            else  /* break if end of string */
                break;
        }
    }
    if (fp != stdin) fclose (fp);

    printf ("\nvalues read from '%s'\n\n", argc > 1 ? argv[1] : "stdin");
    for (i = 0; i < idx; i++)
        printf ("  values[%3zu] : %d\n", i, values[i]);

    return 0;
}

/** a simple strtol implementation with error checking.
 *  any failed conversion will cause program exit. Adjust
 *  response to failed conversion as required.
 */
long xstrtol (char *p, char **ep, int base)
{
    errno = 0;

    long tmp = strtol (p, ep, base);

    /* Check for various possible errors */
    if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
        (errno != 0 && tmp == 0)) {
        perror ("strtol");
        exit (EXIT_FAILURE);
    }

    if (*ep == p) {
        fprintf (stderr, "No digits were found\n");
        exit (EXIT_FAILURE);
    }

    return tmp;
}
使用/输出

所有格式都提供相同的输出,例如:

$ ./bin/fgets_xstrtol_simple <dat/10int_braces.txt

values read from 'stdin'

  values[  0] : 8572
  values[  1] : -2213
  values[  2] : 6434
  values[  3] : 16330
  values[  4] : 3034
  values[  5] : 12346
  values[  6] : 4855
  values[  7] : 16985
  values[  8] : 11250
  values[  9] : 1495

$。/bin/fgetsxstrtol\u simple请先自己尝试一下,看看效果如何。你可以使用
strtok
它更干净一点
scanf
是另一种选择。使用
strtol
并用两个指针处理输入效果很好。@Minato一个包含
scanf
的循环?如果输入数量不多怎么办固定?输入的数量不是固定的
$ ./bin/fgets_xstrtol_simple <dat/10int_braces.txt

values read from 'stdin'

  values[  0] : 8572
  values[  1] : -2213
  values[  2] : 6434
  values[  3] : 16330
  values[  4] : 3034
  values[  5] : 12346
  values[  6] : 4855
  values[  7] : 16985
  values[  8] : 11250
  values[  9] : 1495