如何在C中读取输入

How to read input in C

我正在尝试阅读带有 scanf("%[^\n]") 的一行;就在它之前我正在读取一个带有“%d”的整数,有人告诉我 scanf 在读取后不会删除 '\n',所以我必须调用 fflush() 来避免它,但即使这样做我仍然有同样的问题,所以这是我的代码:

scanf("%d", &n);
fflush(stdin);

lines = (char**)malloc(sizeof(char*)*n);

for(i = 0; i < n; i++){
    lines[i] = (char*)malloc(sizeof(char)*1001);
}

for(i = 0;i < n;i++){
    scanf("%[^\n]", linhes[i]);
}

我读取了一个整数,然后 scanf 没有等待,它开始读取输入 — 不管整数值是多少,无论是 5 还是 10,scanf 都会将所有字符串读取为空。已经尝试使用 fgets,结果几乎相同,只是它读取了一些字符串并跳过了其他字符串。

评论中的BLUEPIXY回答了我的问题:

try "%[^\n]" change to " %[^\n]"

让我们一步步来看:

"... read a line with scanf("%[^\n]");".

scanf("%[^\n]", buf) 不读一行。它几乎确实如此 - 有时。 "%[^\n]" 指示 scanf() 读取任意数量的非 '\n' char 直到遇到一个(然后将 '\n' 放回 stdin)或发生 EOF。

这种方法有一些问题:

  1. 如果第一个 char'\n'scanf() 会把它放回 stdin 而不会改变 bufbuf 保持原样 - 可能 未初始化 scanf() 然后 returns 0.
  2. 如果至少读取了一个非'\n',则将其保存到buf和更多char中,直到出现'\n''[=30=]' 附加到 buf 并且 '\n' 放回 stdinscanf() returns 1. 这种无限性很容易溢出 buf。如果没有保存charEOF或者输入错误,scanf()returnsEOF.
  3. 始终检查 scanf()/fgets() 等函数的 return 值 。如果您的代码不检查它,则 buf 的状态是未知的。

无论如何,'\n'通常仍然留在stdin中,因此没有读完。 '\n' 通常是 next 输入函数的问题。

... scanf doesn't erase the '\n' after reading

另一个常见的误解。 scanf() 读取 '\n' 或不读取,具体取决于提供的格式。有些格式会消耗 '\n',有些则不会。

... call fflush() to avoid it

fflush(stdin) 在某些编译器中定义明确,但不在 C 标准中。通常的问题是代码想要消除 stdin 中的任何剩余数据。当行尾尚未出现时,一种常见的替代方法是读取并处理直到找到 '\n'

int ch;  // Use int
while ((ch = fgetc(stdin)) != '\n' && ch != EOF);

I still have the same problems

IMO,最好的解决方案是读取 用户输入,然后扫描它。

char buf[sizeof lines[i]];
if (fgets(buf, sizeof buf, stdin) == NULL) return NoMoreInput();

// If desired, remove a _potential_ trailing \n
buf[strcspn(buf, "\n")] = 0;

strcpy(lines[i], buf);

我建议缓冲区的大小应约为典型代码预期输入大小的 2 倍。健壮的代码,而不是这个片段,会检测是否需要读取更多的行。 IMO,这种过长的线路通常是黑客的标志,而不是合法使用。