如何在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。
这种方法有一些问题:
- 如果第一个
char
是 '\n'
,scanf()
会把它放回 stdin
而不会改变 buf
! buf
保持原样 - 可能 未初始化 。 scanf()
然后 returns 0.
- 如果至少读取了一个非
'\n'
,则将其保存到buf
和更多char
中,直到出现'\n'
。 '[=30=]'
附加到 buf
并且 '\n'
放回 stdin
和 scanf()
returns 1. 这种无限性很容易溢出 buf
。如果没有保存char
而EOF
或者输入错误,scanf()
returnsEOF
.
- 始终检查
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,这种过长的线路通常是黑客的标志,而不是合法使用。
我正在尝试阅读带有 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。
这种方法有一些问题:
- 如果第一个
char
是'\n'
,scanf()
会把它放回stdin
而不会改变buf
!buf
保持原样 - 可能 未初始化 。scanf()
然后 returns 0. - 如果至少读取了一个非
'\n'
,则将其保存到buf
和更多char
中,直到出现'\n'
。'[=30=]'
附加到buf
并且'\n'
放回stdin
和scanf()
returns 1. 这种无限性很容易溢出buf
。如果没有保存char
而EOF
或者输入错误,scanf()
returnsEOF
. - 始终检查
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,这种过长的线路通常是黑客的标志,而不是合法使用。