在调用
我发现有些答案建议在第一次调用
然而,尽管我已经看到有些答案中这些方法起作用,但我无法在此处使它们起作用(如下所示的代码)。 为什么这两种
以下方法是唯一能按预期工作的方法:
scanf("%d", &variable);
后,我们会在 stdin 中留下一个未处理的换行符,需要在调用 fgets
之前清除它,否则会导致它提前返回并读取到换行符。我发现有些答案建议在第一次调用
scanf
后使用 scanf("%*[^\n]%*c");
来丢弃换行符,而另一些建议使用 scanf("%*[^\n]\n");
。理论上,两种方法都可以:第一种方法会消耗除了换行符以外的任何字符(但不包括换行符本身),然后消耗 恰好 一个字符(即换行符)。第二种方法会消耗除了换行符以外的任何字符(不包括它本身),然后 \n
这个空白字符会指示 scanf
读取所有的空白字符,直到遇到第一个非空白字符。然而,尽管我已经看到有些答案中这些方法起作用,但我无法在此处使它们起作用(如下所示的代码)。 为什么这两种
scanf
方法都不起作用?
测试环境:
Ubuntu Linux - gcc
5.4.0
scanf("%*[^\n]\n");
方法:
#include <stdio.h>
int main(int argc, char **argv){
int number;
char buffer[1024];
printf("Write number: \n");
scanf("%d", &number);
//Clearing stdin?
scanf("%*[^\n]\n");
printf("Write phrase: \n");
fgets(buffer, 1024, stdin);
printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);
return 0;
}
输出:
$ ./bug
Write number:
2
Write phrase:
You wrote:2 and "
"
scanf("%*[^\n]%*c");
approach:
#include <stdio.h>
int main(int argc, char **argv){
int number;
char buffer[1024];
printf("Write number: \n");
scanf("%d", &number);
//Clearing stdin?
scanf("%*[^\n]%*c");
printf("Write phrase: \n");
fgets(buffer, 1024, stdin);
printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);
return 0;
}
输出:
$ ./bug2
Write number:
3
Write phrase:
You wrote:3 and "
"
以下方法是唯一能按预期工作的方法:
有效方法:
#include <stdio.h>
int main(int argc, char **argv){
int number;
char buffer[1024];
printf("Write number: \n");
scanf("%d", &number);
//Clearing stdin!
int c;
while((c = getchar()) != '\n' && c != EOF){
//Discard up to (and including) newline
}
printf("Write phrase: \n");
fgets(buffer, 1024, stdin);
printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);
return 0;
}
输出:
$ ./notbug
Write number:
4
Write phrase:
phrase :D
You wrote:4 and "phrase :D
"
scanf
清除挂起的换行符的方法不能像预期的那样工作。 - IanCgets
。它是危险的,并且已经不再是标准的一部分了。 - too honest for this sitefgets
而不是使用scanf
? - too honest for this sitefgets
更加直接,不会在stdin缓冲区上产生挂起字符的问题。我实际上在回答一个使用scanf
的问题时遇到了这个疑问。 - IanC