为什么会跳过scanf?

zsc37201 2008-03-20 05:35:21
#include<stdio.h>

void main()
{
int x;
while(1)
{

printf("Please input a integer:\n");
scanf("%d",&x);
if(x>=1000 || x<=0)
printf("The number you input is invalid.\n");
else
if(x>=100)
printf("The number has 3 digits.\n");
else if(x>=10)
printf("The number has 2 digits.\n");
else
printf("The number has 1 digit.\n");

}
}
源代码如上,当输入整数时反应正常, 但当输入小数(如3.4),就会陷入快速死循环, 好像跳过了scanf语句. 但把代码改成如下时, 反应正常. 不知是为什么, 我刚学编程,请大虾指导一下.
#include<stdio.h>

void main()
{
float x;
while(1)
{

printf("Please input a integer:\n");
scanf("%f",&x);
if(x>=1000 || x<=0)
printf("The number you input is invalid.\n");
else
if(x>=100)
printf("The number has 3 digits.\n");
else if(x>=10)
printf("The number has 2 digits.\n");
else
printf("The number has 1 digit.\n");

}
}
...全文
451 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ThunderFAE 2012-05-23
  • 打赏
  • 举报
回复
果断学习,受教了。。
萧乐颜 2008-03-21
  • 打赏
  • 举报
回复
4楼的,我又学到了点点.
brookmill 2008-03-20
  • 打赏
  • 举报
回复
路过
Lynn_Ran 2008-03-20
  • 打赏
  • 举报
回复
最好不要使用fflush(stdin);
首先看以下程序:

#include <stdio.h>

int main( void )
{
int i;
for ( ; ; )
{
fputs("Please input an integer: ", stdout);
scanf("%d", &i);
printf("%d\n", i);
}
return 0;
}


这个程序首先会提示用户输入一个整数,然后等待用户输入,如果用户输入的是整数,程序会输出刚才输入的整数,并且再次提示用户输入一个整数,然后等待用户输入。但是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次得到的整数是 2 ,那么程序会不停地输出“Please input an integer: 2”。这是因为 scanf("%d", &i); 只能接受整数,如果用户输入了字母,则这个字母会遗留在“输入缓冲区”中。因为缓冲中有数据,故而 scanf 函数不会等待用户输入,直接就去缓冲中读取,可是缓冲中的却是字母,这个字母再次被遗留在缓冲中,如此反复,从而导致不停地输出“Please input an integer: 2”。
就像2楼说的:“居然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就行了?”然而这是错的!C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(linux 下的 gcc 就不支持),因为标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着fflush on input stream is an extension to the C standard(fflush 操作输入流是对 C 标准的扩充)。当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。以下是 C99 对 fflush 函数的定义:

int fflush(FILE *stream);

如果 stream 指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么 fflush 函数将把这个流中任何待写数据传送至
宿主环境(host environment)写入文件。否则,它的行为是未定义的。原文如下:

int fflush(FILE *stream);

If stream points to an output stream or an update stream in whichthe most recent operation was not input, the fflush function causesany unwritten data for that stream to be delivered to the host environmentto be written to the file; otherwise, the behavior is undefined.

其中,宿主环境可以理解为操作系统或内核等。由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的,至少是移植性不好的。


以下是这个问题的解决办法:


#include <stdio.h>
#include <iostream>

void main()
{
int x, c;
while ( 1 )
{
printf("Please input a integer:\n");
scanf("%d",&x);
if ( x>=1000 || x<=0 )
printf("The number you input is invalid.\n");
else if ( x >= 100 )
printf("The number has 3 digits.\n");
else if ( x >= 10 )
printf("The number has 2 digits.\n");
else
printf("The number has 1 digit.\n");
while ( (c = getchar()) != '\n' && c != EOF ) ;//<====There~
}
return;
}
abupie 2008-03-20
  • 打赏
  • 举报
回复
缓冲区, 加fflush().
thecorr 2008-03-20
  • 打赏
  • 举报
回复
缓冲区的问题
独孤过儿 2008-03-20
  • 打赏
  • 举报
回复

#include <stdio.h>

int main()
{
int x;
while (1)
{
printf("Please input a integer:\n");
scanf("%d", &x);
if (x>=1000 || x <=0)
printf("The number you input is invalid.\n");
else if (x >= 100)
printf("The number has 3 digits.\n");
else if (x >= 10)
printf("The number has 2 digits.\n");
else
printf("The number has 1 digit.\n");
fflush(stdin); //清空一下缓冲区就好了
}
return 0;
}

64,849

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧