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

从stdin(C)读取未知数量的整数,c,stdin,integer,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。有什么办法吗?通过以下方式运行输入文件: #include <stdio.h> int main() { int k; wh

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

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。有什么办法吗?

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

#include <stdio.h>

int main() {
        int k;
        while (scanf("%d", &k) == 1) {
                printf("read number: %d\n", k);
        }
        return 0;
}
#包括
int main(){
int k;
而(scanf(“%d”,&k)==1){
printf(“读取编号:%d\n”,k);
}
返回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 阅读编号:1 阅读编号:19 阅读编号:20 阅读编号:41 阅读编号:23 阅读编号:2 阅读编号:41 阅读编号:52 阅读编号:43 阅读编号:3 阅读编号:90 阅读编号:91 阅读号码:941 阅读编号:4 阅读编号:512 阅读编号:5 阅读编号:6 阅读编号:51 阅读编号:61
这是您在原始问题中引用的代码的C模拟。

请看一下getc(3)或scanf(3)

我将其分解为两个操作:读取一行,然后读取该行中的整数。下面是一个使用标准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
    }
}
我会做以下一件事:

  • fgetc()读取单个字符并自己解析它们(累积数字,直到碰到空格,并且有一个整数要用atoi()转换;如果空格是换行符,则它会终止一个整数列表)

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


    • 我会在不同的任务中中断程序

      第一步是能够读一对行,第一行告诉你要读的数字,然后第二行读实际数字。为此,一个名为
      read\u 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\u 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\u set()
      :它必须读取两行。有很多,所以您可以使用其中的任何一个,先读取一行,然后读取一个数字(检查其返回值!)。一旦有了数字编号,
      n
      ,就可以读取内存中的下一行,并执行以下操作:

      num->data = malloc(n * sizeof *num->data);
      num->len = n;
      
      然后,您可以反复调用
      sscanf()
      strtol()
      将数字存储在
      num->data
      中。您应该进行检查,以确保
      n
      数字准确地位于该行


      请注意,您也可以用其他方式编写
      read_set()
      :逐行读取一个字符,并在读取时解析数字。这样做的优点是只需对数据进行一次检查,并且不需要大的缓冲区来将整个输入行存储在内存中,但缺点是自己做低级工作,一个字符一个字符地读取数据可能会很慢。

      我提出了这样一个解决方案:

      #包括
      内部主(空)
      {
      int指数=0;
      char ch;
      int-arr[1024];
      而(scanf(“%d%c”、&arr[index++]、&ch)!=EOF)
      {
      如果(ch='\n')
      {
      //一行被读入arr
      //此行中的整数数=索引
      //可以处理arr[]的其余代码
      //范例
      int i;
      对于(i=0;i
      您需要注意行吗,还是这只是一系列的整数?在你的例子中,看起来奇数行是序列号,偶数行代表其他东西。david我需要注意这些行。这就是我不能做这件事的原因。我需要停止在每个偶数行的末尾获取新值。因为我有一个带有属性id和list的结构。每一奇数行是一个id,每一偶数行是一个列表。我想用两行数据填充一个结构,然后移动到另一个结构,用另外两行数据填充它,等等…一次读取一整行数据,然后将其作为字符串解析,非常感谢。我现在就试试。但是如果我不能假定一个固定的最大行长呢?如果输入流包含超过1024-2个字符并且
      fgets()
      以数字文字分割输入流呢?您将得到两个数值,而不是一个。例如,从12345开始,在下一次调用
      fgets()
      之后,可以在For循环的最后一次迭代中得到123,在For循环的第一次迭代中得到45。因此,对于这项任务,我更喜欢
      scanf()
      fscanf()
      ,如肖恩所示。@RobinKlose:Sean发布的
      scanf()
      解决方案不能解决问题,因为它不能区分换行符和其他空格。@DietrichEpp:好的,我明白你的意思。发问者需要跟踪这些线。但是,您是否看到了一种解决上述问题的简单方法?请注意,
      getline()
      是POSIX标准的一部分,它只是在Windows上不可用。我可以正确地读取该行,但scanf循环会无限地为我打印第一个数字。