我需要做以下事情:
int main(void) {
char a,b,cstring;
printf("please enter something");
scanf("%c %c",&a,&b);
prinf("thanks, now some more");
fgets(cstring,35,stdin);
}
问题是每当我从scanf输入第一个变量时,它都会跳到程序的末尾。我该如何做多个输入?
答案 0 :(得分:7)
第一个问题是scanf()
读取了两个字符,但后来没有读取换行符。
这意味着您的fgets()
会读取换行符并完成。
你很幸运,你的程序没有崩溃。你告诉fgets()
它正在获得一个包含35个字符的数组,但是你传递的是字符(而不是字符的地址,而不是传递数组)。这也告诉我们你不是包括编译时启用了足够的警告,或者没有足够重视编译器告诉你的内容。#include <stdio.h>
(你不能根据C标准可靠地使用scanf()
而没有范围内scanf()
的原型,而你不是
您应该收到编译器警告。例如,GCC 4.6.0说:
/usr/bin/gcc -g -I/Users/jleffler/inc -std=c99 -Wall -Wextra -Wmissing-prototypes \
-Wstrict-prototypes -Wold-style-definition xxx.c
xxx.c: In function ‘main’:
xxx.c:7: warning: implicit declaration of function ‘prinf’
xxx.c:8: warning: passing argument 1 of ‘fgets’ makes pointer from integer without a cast
并且,在我尝试链接之前,我甚至没有注意到prinf()
对printf()
的拼写错误,并且编辑器通过说“不知道是什么{来揉捏我的鼻子” {1}}是!“。
如果你的编译器至少没有给出第二个警告,那就给自己一个更好的编译器。
注释:
如何阻止它在阅读换行符之后?
问题不是阻止prinf()
阅读换行符;问题实际上是如何让它读取它,以便scanf()
在下一行输入中获得清晰的运行。它实际上是非常棘手的 - 我很少使用fgets()
的原因之一(但我经常使用scanf()
)。这可以完成简单输入的工作:
sscanf()
#include <stdio.h>
int main(void)
{
char a,b,cstring[35];
printf("please enter something");
scanf("%c %c%*c", &a, &b);
printf("thanks, now some more");
fgets(cstring, 35, stdin);
printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring);
return 0;
}
读取一个额外的字符(换行符)而不将其分配到任何地方(这是因为%*c
)。但是,如果第二个非空白后有多个字符,则无济于事。我可能会写一个循环来读取换行符:
*
请注意,#include <stdio.h>
int main(void)
{
char a,b,cstring[35];
int c;
printf("please enter something");
scanf("%c %c", &a, &b);
while ((c = getchar()) != EOF && c != '\n')
;
printf("thanks, now some more");
fgets(cstring, 35, stdin);
printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring);
return 0;
}
会返回getchar()
而不是int
。这可靠地丢弃第一行输入上的所有内容。它还显示了如何回显您所读取的内容 - 这是调试的一个重要部分。
答案 1 :(得分:1)
这是未定义的行为。您的cstring
变量,无论其名称是什么,都是一个字符,并且您尝试将最多35个字符读取为其当前值指向的字符。换句话说,cstring
中的当前字符将转换为指针,它将尝试在那里写入您的输入。这将是一个介于0到255之间的内存位置(最有可能)。
这就是导致细分违规的原因。从这样的事情开始:
#include <stdio.h>
int main(void) {
char a,b,cstring[99];
printf("please enter something");
scanf("%c %c",&a,&b);
printf("thanks, now some more");
fgets(cstring,35,stdin);
return 0;
}
或者,可能更好:
#include <stdio.h>
int main(void) {
char a,b,cstring[99];
printf("please enter something");
fgets(cstring,35,stdin);
sscanf(cstring,"%c %c",&a,&b);
printf("thanks, now some more");
fgets(cstring,35,stdin);
return 0;
}
或者,如果您想要一个更强大的用户输入解决方案,请参阅here。这是一种久经考验的方法,具有非常好的错误检查功能。
答案 2 :(得分:0)
问题是当流程到达fgets()时,此API首先查看stdin以获取输入,并在那里找到一个迷路'\ n'。至于fgets(),它表示此API在遇到EOF或'\ n'时返回,因为fgets()从stdin获得'\ n',所以它执行时无需等待用户输入内容,因为API返回条件满足。< / p>
问题的解决方法是使用getchar();在scanf之后,忽略scanf()留下的额外字符。 e.g:
scanf("%lf",&e);
getchar();
fgets(t,200,stdin);
或
其他解决方案可以是使用带有fgets的sscanf。 e.g:
#include <stdio.h>
int main() {
int j;char t[200];
fgets(t,200,stdin);
sscanf(t,"%d",&j);
}
答案 3 :(得分:-1)
使用scanf后可以使用fflush(stdin)来解决问题