第一个问题是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() 的拼写错误,直到我尝试链接并且编译器揉了揉我的鼻子说“不知道 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。这可靠地丢弃了第一行输入的所有内容。它还展示了如何回显您阅读的内容 - 调试的重要部分。