我需要做类似以下的事情:
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的第一个变量时,它就会跳到程序的末尾。我如何进行多次输入?
scanf()
读取了两个字符,但没有读取换行符。fgets()
读取了换行符并结束了。fgets()
它要获取一个长度为35的字符数组,但你传递了一个字符(甚至不是字符的地址)。这也告诉我们你没有包含 #include <stdio.h>
(如果没有在作用域中定义scanf()
的原型,则不能可靠地使用scanf()
),并且你没有启用足够的编译器警告,或者没有足够注意编译器的提示。/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()
的拼写错误,直到我尝试链接并且编译器通过说“不知道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
而不是char
。这可靠地丢弃了输入的第一行所有内容。它还显示了如何回显所读取的内容-调试的重要部分。#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;
}
或者,如果您想要一个更强大的用户输入解决方案,请查看这里。这是一种经过验证和测试的方法,具有非常好的错误检查功能。
scanf("%lf",&e);
getchar();
fgets(t,200,stdin);
或者
另一个解决方案是结合fgets使用sscanf. 例如:
#include <stdio.h>
int main() {
int j;char t[200];
fgets(t,200,stdin);
sscanf(t,"%d",&j);
}
fflush
是一个输出操作(它将缓冲数据写入底层流)。在像 stdin
这样的输入句柄上使用它会产生未定义的行为。 - melpomene
scanf()
是否成功读取了两个字符;它应该这样做。它还应该检查fgets()
是否也有输入。然而,那会稍微使答案变得混乱一些,让你更难以看到问题的本质。 - Jonathan Leffler