为什么 scanf() 不等待键盘输入?
Why isn't scanf( ) waiting for input from keyboard?
我有以下 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);
在正确的地方。我不希望 return 键在下一个 scanf() 的缓冲区中。
为了调试,我尝试不使用 fflush(stdin) 并查看有什么问题。但即使没有 fflush(stdin),当我 运行 程序时也会发生同样的事情。所以我猜 fflush(stdin) 不会导致这个问题。
请大家指出,我的程序哪里出错了?
谢谢。
C11 标准解释了 %c
的工作原理:
§7.21.6.2/8 Input white-space characters (as specified by the isspace
function)
are skipped, unless the specification includes a [
, c
, or n
specifier.
因此,回车键产生的换行被 %c 消耗了。您可以通过在 %c
:
之前添加 space 来解决此问题
§7.21.6.2/5 A directive composed of white-space character(s) is
executed by reading input up to the first non-white-space character
(which remains unread), or until no more characters can be read. The
directive never fails.
您的代码变为 scanf(" %c%f%d",&b[i].name,&b[i].price,&b[i].pages);
。
请注意,此处应fflush
不。
§7.21.5.2/2 If stream
points to an output stream or an update stream in which
the most recent operation was not input, the fflush
function causes
any unwritten data for that stream to be delivered to the host
environment to be written to the file; otherwise, the behavior is
undefined.
我有以下 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);
在正确的地方。我不希望 return 键在下一个 scanf() 的缓冲区中。
为了调试,我尝试不使用 fflush(stdin) 并查看有什么问题。但即使没有 fflush(stdin),当我 运行 程序时也会发生同样的事情。所以我猜 fflush(stdin) 不会导致这个问题。
请大家指出,我的程序哪里出错了?
谢谢。
C11 标准解释了 %c
的工作原理:
§7.21.6.2/8 Input white-space characters (as specified by the
isspace
function) are skipped, unless the specification includes a[
,c
, orn
specifier.
因此,回车键产生的换行被 %c 消耗了。您可以通过在 %c
:
§7.21.6.2/5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.
您的代码变为 scanf(" %c%f%d",&b[i].name,&b[i].price,&b[i].pages);
。
请注意,此处应fflush
不。
§7.21.5.2/2 If
stream
points to an output stream or an update stream in which the most recent operation was not input, thefflush
function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.