我正在尝试使用 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,结果几乎相同,只是它读取一些字符串并跳过其他字符串。
最佳答案
让我们一步一步来看:
"... read a line with scanf("%[^\n]");".
scanf("%[^\n]", buf)
不读取一行。几乎确实如此——有时。 "%[^\n]"
指示 scanf()
读取任意数量的非 '\n'
char
直到遇到一个('\n'
然后被放回 stdin
)或发生 EOF。
这种方法有一些问题:
- 如果第一个
char
是'\n'
,则scanf()
将其放回stdin
,而无需无论如何改变buf
!buf
保持原样 - 也许未初始化。scanf()
然后返回 0。 - 如果至少读取一个非
'\n'
,则将其保存到buf
和更多char
中,直到发生出现“\n”
。'\0'
被附加到buf
中,'\n'
被放回stdin
和scanf()
返回 1。这种无限性很容易溢出buf
。如果没有保存char
并且发生EOF
或输入错误,scanf()
返回EOF
。 - 始终检查
scanf()
/fgets()
等函数的返回值。如果您的代码没有检查它,则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
在我看来,最好的解决方案是读取一行用户输入,然后扫描它。
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,这种过长的线路通常是黑客的迹象,而不是合法使用。
关于c - 如何读取C中的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30881102/