在不立即使用数组和 printf 的情况下扫描未知数量的整数

Scanf an unknown amount of integers without using array and printf right away

(我是新手) 我需要使用循环来 scanf 未知数量的整数而不使用数组直到 Ctrl-D 并在循环进行时打印它们。 例如,输入可以是:

140 128 8 1603 
4905 -3 -2 0 0 
9166 255 -1322 
8900 10000 -1 6543 

在这种情况下输出应该是:

140, 128, 8, 1603, 4905, -3, -2, 0, 0, 9166, 255, -1322, 8900, 10000, -1, 6543

现在,当我尝试写类似

的东西时
while (scanf("%d", &number)) {
    /* code */
    printf("%d, ", number);
    /* code */
}

scanf 将扫描值直到它看到 \n,然后打印它扫描的每个值并重复直到 Ctrl-D,这导致我的输入与我的输出混淆了:

140 128 8 1603 
140, 128, 8, 1603, 4905 -3 -2 0 0 
4905, -3, -2, 0, 0, 9166 255 -1322
9166, 255, -1322, 8900 10000 -1 654

我能得到一些关于避免这种情况的编码技术的建议吗?在这种情况下,什么是不打印最后一个逗号的最佳检查?

不打印最后一个逗号的可能方法(在这种情况下,我们首先打印逗号,除非它是我们扫描的第一个元素):

#include <stdio.h> // scanf(), printf()
#include <stdbool.h> // bool, true, false

int main(void) {
  int number;

  bool first_scan = true;
  while (scanf("%d", &number) == 1) {
    if (first_scan != true) {
      printf(", ");
    }
    printf("%d", number);
    first_scan = false;
  }
  printf("\n");

  return 0;
}

如果您编写的文件 test.txt 包含:

1 2 3
4 5 6

而你 运行 你的程序是这样的:

./program < test.txt

你得到这个输出:

1, 2, 3, 4, 5, 6

注意:scanf() 不太适合这个目的,因为它不会检测整数溢出(而且它也会让你很头疼),所以 [=21 通常是个好习惯=].在这种情况下,另一种方法是使用 fgets()strtoll(),但这超出了本答案的范围。

编辑:我之前的注释非常含糊(感谢 Steve Summit):当我说“scanf() 不适合这个”时,我的意思是“不适合读取整数real-world application”,但对于像你这样的初级程序来说,这很好。但是,当您对 C 变得更加熟悉(并开始编写更复杂的应用程序)时,您应该看一下 fgets()strtoll()(如果您还没有准备好的话,还没有),所以您能写出更多正确的程序。

您的代码几乎是正确的:应该只测试 while (scanf("%d", &number) == 1) 而不是 != 0,因为 scanf() 将 return EOF 放在文件末尾。

如果有另一个号码,您可能只想打印 ,。按照编码,输出将有一个尾随逗号。您可以通过在 之前打印 ", " 除了第一个数字之外的每个数字来做到这一点。

您对程序行为的解释有点不正确:scanf() 似乎转换并保留所有值直到换行符的原因是 stdin 在您的系统上进行了行缓冲,因此输入不可用到 scanf() 直到读完一整行文本。此外,在终端级别还有另一层缓冲,因此如果您从终端读取,则将 stdin 的缓冲方案更改为 setvbuf() 是不够的。