从stdin读取未知数量的整数(C)

时间:2010-02-03 22:03:11

标签: c stdin integer

我需要读取输入文件,如:

1
19 20 41 23
2
41 52 43
3
90 91 941
4
512
5

6
51 61

每个奇数行是一个整数。每个偶数行都是未知的整数。

在C ++中非常容易

while( cin >> k ){
............
}

我不习惯C,所以我无法用C语言。任何方法都可以吗?

6 个答案:

答案 0 :(得分:12)

通过以下方式运行输入文件:

#include <stdio.h>

int main() {
        int k;
        while (scanf("%d", &k) == 1) {
                printf("read number: %d\n", k);
        }
        return 0;
}

结果:

read number: 1
read number: 19
read number: 20
read number: 41
read number: 23
read number: 2
read number: 41
read number: 52
read number: 43
read number: 3
read number: 90
read number: 91
read number: 941
read number: 4
read number: 512
read number: 5
read number: 6
read number: 51
read number: 61

这是您在原始问题中引用的代码的C模拟。

答案 1 :(得分:9)

我这样做的方法是将其分解为两个操作:读取一行,然后读取该行中的整数。这是使用标准C库的惰性实现:

char line[1024], *p, *e;
long v;
while (fgets(line, sizeof(line), stdin)) {
    p = line;
    for (p = line; ; p = e) {
        v = strtol(p, &e, 10);
        if (p == e)
            break;
        // process v here
    }
}

答案 2 :(得分:3)

我会在不同的任务中打破程序。

第一步是能够读取一对线,第一行告诉你要读取的数字,然后第二行读取实际数字。为此,一个名为read_set的函数可能很有用。它应该能够返回读取的数字,并发出文件结束和错误信号。为此,我们可以定义一个数据结构,例如:

struct numbers {
    long *data; /* or choose a type depending upon your needs */
    size_t len;
};

然后我们可以用原型声明我们的函数:

int read_set(FILE *fp, struct numbers *num);

该函数将为num->data分配内存,并将num->len设置为正确的值。它返回0表示成功,否则返回一组错误条件。我们可能会看上去并稍后使用enum作为返回状态。现在,假设0 =成功,1 =文件结束,其他一切都是错误。

然后,呼叫者在循环中调用read_set()

struct numbers numbers;
int status;
while ((status = read_set(fp, &numbers)) == 0) {
    /* process numbers->data, and then free it */
}
if (status == 1) {
    /* hit end of file, everything is OK */
} else {
    /* handle error */
}

实施read_set():它必须读两行。有很多implementations of reading a full line in C,所以你可以使用它们中的任何一个,先读一行,然后sscanf() / strtoul()一个数字(检查它的返回值!)。获得数字n后,您可以读取内存中的下一行,并执行以下操作:

num->data = malloc(n * sizeof *num->data);
num->len = n;

然后,您可以反复拨打sscanf()strtol()来存储num->data中的号码。您应该进行检查以确保该行上确实有n个数字。

请注意,您也可以用其他方式编写read_set():逐个字符地读取一行,并在读取时解析这些数字。这样做的好处是只需将数据翻过一次,而不需要一个大的缓冲区来将整个输入行存储在内存中,但缺点是自己做低级别的东西,逐个字符地读取数据可能会很慢。 / p>

答案 3 :(得分:1)

我会做一个:

  • fgetc()读取单个字符并自己解析它们(累积数字,直到你点击空格,你有一个整数与atoi()转换;如果空格是换行符,那么它终止一个整数列表)

  • fgets()一次读取一行,然后解析它返回的字符串(再次查找分隔值的空格)。

答案 4 :(得分:0)

看看getc(3)或scanf(3)

答案 5 :(得分:0)

我提出了这样的解决方案:

while(scanf("%d%c", &n, &ch)!=EOF)
{
    if(ch=='\n') break;
    /* rest of your code */
}