[英]Why aren't scanf(“%*[^\n]\n”); and scanf(“%*[^\n]%*c”); clearing a hanging newline?
在调用scanf("%d", &variable);
我们在stdin上留下了换行符,应该在调用fgets
之前清除该换行符,否则我们最终将其换行,并使其过早返回。
我找到了建议使用scanf("%*[^\\n]%*c");
答案scanf("%*[^\\n]%*c");
在第一次调用scanf
放弃换行符后,其他人建议使用scanf("%*[^\\n]\\n");
。 从理论上讲,这两个应该工作:首先将消耗所有不换行(但不包括新行本身),然后消耗的一个字符(新行)。 第二个将消耗掉所有不是换行符的内容(不包括换行符),然后\\n
(一个空格字符)将指示scanf
读取每个空格字符,直到第一个非空格字符为止。
但是,就我看来,这些方法在某些答案中可以起作用,但我无法在这里使它们起作用(下面的代码)。
为什么两种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");
方法: #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模式%[^\\n]
与不是换行符的一个或多个字符匹配。 因此,如果下一个字符是换行符,则模式将失败并且scanf
将立即返回而不会读取任何内容。 添加*
不会更改该基本事实。 因此,事实证明您不能仅凭一个电话就可以做到这一点,您需要两个:
scanf("%*[^\n]"); scanf("%*c");
请注意,将空白的换行符放在扫描模式中几乎总是无用的,因为它会使scanf读取并丢弃所有空白,直到看到一个非空白字符(它将留在输入缓冲区中)。 特别是如果您尝试在交互式程序中使用它,它将显示为挂起状态,直到您输入非空白行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.