我见过几个例子,人们给 scanf 一个 "%[^\n]\n"
格式字符串来读取整行用户输入。如果我的理解是正确的,这将读取每个字符,直到到达换行符,然后换行符被 scanf 消耗(并且不包含在结果输入中)。
但我不能让它在我的机器上运行。我试过的一个简单例子:
#include <stdio.h>
int main(void)
{
char input[64];
printf("Enter some input: ");
scanf("%[^\n]\n", input);
printf("You entered %s\n", input);
}
当我运行它时,系统提示我输入,我输入了一些字符,我按下 Enter,然后光标转到下一行的开头,但 scanf 调用没有完成。
我可以按 Enter 键多次,而且它永远不会完成。
我发现结束 scanf 调用的唯一方法是:
- 在提示符处输入
\n
作为第一个(也是唯一一个)字符 - 在提示符处输入 Ctrl-d 作为第一个(也是唯一一个)字符
- 输入一些输入,一个或多个
\n
,零个或多个其他字符,然后输入Ctrl-d
我不知道这是否与机器有关,但我很想知道发生了什么。如果相关的话,我在 OS X 上。
最佳答案
根据documentation对于 scanf(强调我的):
The format string consists of whitespace characters (any single whitespace character in the format string consumes all available consecutive whitespace characters from the input), non-whitespace multibyte characters except
%
(each such character in the format string consumes exactly one identical character from the input) and conversion specifications.
因此,您的格式字符串 %[^\n]\n
将首先从输入中读取(并存储)任意数量的非空白字符(因为 %[ ^\n]
部分),然后,由于下面的换行符,读取(并丢弃)任意数量的空白字符,例如空格、制表符或换行符。
因此,要使您的 scanf 停止读取输入,您需要在换行符后至少键入一个 非空白 字符,或者安排输入流结束(例如,通过按 < kbd>Ctrl+D 在 Unix-ish 系统上)。
相反,要使您的代码按预期工作,只需从格式字符串末尾删除最后一个 \n
(正如 Umamahesh P 所建议的那样)。
当然,这会将换行符留在输入流中。要摆脱它(如果你想稍后阅读另一行),你可以 getc它离开流,或者只是附加 %*c
(这意味着“读取一个字符并丢弃它”)甚至 %*1[\n]
(读取一个换行符并将其丢弃)到 scanf 格式字符串的末尾。
Ps. 请注意,您的代码还有一些其他问题。例如,为了避免缓冲区溢出错误,您确实应该使用 %63[^\n]
而不是 %[^\n]
来限制 scanf 将要执行的字符数读入你的缓冲区。 (该限制需要比您的缓冲区大小小一,因为 scanf 将始终附加一个尾随空字符。)
此外,%[
格式说明符总是需要至少一个匹配字符,如果没有匹配字符就会失败。因此,如果您在不输入任何内容的情况下立即按回车键,您的 scanf 将失败(无提示,因为您不检查返回值)并且会使您的输入缓冲区充满随机垃圾。为避免这种情况,您应该 a) 检查 scanf 的返回值,b) 在调用 scanf 之前设置 input[0] = '\0'
,或者 c) 最好两者兼而有之。
最后,请注意,如果您只想逐行读取输入,使用 fgets 会更容易 .是的,如果你不想要尾随的换行符(如果有的话),你需要自己去掉它,但是这仍然比尝试使用 scanf 来完成它并不真正意味着的工作更容易和更安全:
#include <stdio.h>
#include <string.h>
void chomp(char *string) {
int len = strlen(string);
if (len > 0 && string[len-1] == '\n') string[len-1] = '\0';
}
int main(void)
{
char input[64];
printf("Enter some input: ");
fgets(input, sizeof(input), stdin);
chomp(input);
printf("You entered \"%s\".\n", input);
}
关于c - 为什么这个 scanf 格式字符串不起作用? "%[^\n]\n",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35255891/