我有以下C代码。
#include<stdio.h>
int main()
{
//Declaring structure book.
struct book
{
char name;
float price;
int pages;
};
struct book b[5];
int i;
//Below loop takes the info if 5 books from user
for (i=0; i<5; i++)
{
printf("Enter name, price, and pages: ");
fflush( stdin );
scanf("%c%f%d",&b[i].name,&b[i].price,&b[i].pages);
}
return 0;
}
然而,当我编译并运行时,会发生一些奇怪的事情。
-bash-4.1$ ./a.out
Enter name, price, and pages: A 23 34
Enter name, price, and pages: B 34 54
Enter name, price, and pages: Enter name, price, and pages: C 56 78
Enter name, price, and pages: -bash-4.1$
你可以看到,当i = 2时,scanf()不会等待键盘。然后当i = 3时,scanf()等待键盘输入。再次在i = 4中,scanf()不等待键盘输入。
我想我已经使用了
fflush(stdin);
在正确的地方。我不希望返回键在下一个scanf()中的缓冲区中。
要调试,我尝试不使用fflush(stdin)并查看heppens。但即使没有fflush(stdin),当我运行程序时也会发生同样的事情。所以我猜fflush(stdin)不会导致这个问题。
请有人指出,我的程序出错了吗?
感谢。
答案 0 :(得分:4)
C11标准解释了%c
的工作原理:
§7.21.6.2/ 8输入空格字符(由
isspace
函数指定) 被跳过,除非规范包含[
,c
或n
说明符。
因此,输入键产生的换行由%c消耗。您可以通过在%c
之前添加空格来解决此问题:
§7.21.6.2/ 5由白色空格字符组成的指令是 通过读取输入到第一个非空白字符来执行 (仍然未读),或直到不再能读取任何字符。该 指令永远不会失败。
您的代码变为scanf(" %c%f%d",&b[i].name,&b[i].price,&b[i].pages);
。
请注意,此处fflush
应
§7.21.5.2/ 2如果
stream
指向输出流或其中的更新流 最近的操作未输入,fflush
函数导致 要传递给主机的该流的任何未写入数据 要写入文件的环境;否则,行为是 未定义。强>