注册 登录
编程论坛 C++教室

新手求助C++的一个疑惑

veikin 发布于 2010-10-21 10:03, 1233 次点击
先看程序:
#include<iostream.h>

void main()
{
        int year,i;
        cout<<"year=";
        cin>>year;
        if(year<0)
                cout<<"input error!"<<endl;
        while(year>=0 && year<=130)
        {
                i=year/10;
                switch(i)
                {
                case 0:
                        cout<<"小孩"<<endl;
                        break;
                case 1:
                        cout<<"少年"<<endl;
                        break;
                case 2:
                        cout<<"青年"<<endl;
                        break;
                case 3:
                case 4:
                        cout<<"中年"<<endl;
                        break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                        cout<<"老年"<<endl;
                        break;
                default:
                        cout<<"input error!"<<endl;
                }
                cout<<"input year=";
                cin>>year;
        }
}


问当我输入year值为小数的时候,为什么会进入死循环? 而且循环输出内容都为:“input year =小孩”
21 回复
#2
书中叶2010-10-21 10:38
因为year是int整型的
小数属于浮点型
#3
myth_feng2010-10-21 10:41
    fflush(stdin);   //清空cin缓存区
    cout<<"input year=";
    cin>>year;
#4
xinyuan542010-10-21 11:00
楼上正解!!
程序代码:
#include "stdafx.h"
#include "iostream"
using namespace std;


void main()
{
        float year;
        int i;
        cout<<"year=";
        cin>>year;
        if(year<0)
                cout<<"input error!"<<endl;
        while(year>=0 && year<=130)
        {
                i=year/10;
                switch(i)
                {
                case 0:
                        cout<<"小孩"<<endl;
                        break;
                case 1:
                        cout<<"少年"<<endl;
                        break;
                case 2:
                        cout<<"青年"<<endl;
                        break;
                case 3:
                case 4:
                        cout<<"中年"<<endl;
                        break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                        cout<<"老年"<<endl;
                        break;
                default:
                        cout<<"input error!"<<endl;
                }            

                cout<<"input year=";
                cin>>year;
        }
}
不过也可以把year定义成float这样也能解决问题!!~~
#5
书中叶2010-10-21 11:03
把while改成if试一下,再把main块里的东西用for(;;){}括起来就行了

[ 本帖最后由 书中叶 于 2010-10-21 11:04 编辑 ]
#6
veikin2010-10-21 11:34
回复 2楼 书中叶
是呀,将year 改为double型以后就正常,但是我很好奇的就是为什么year设置为整形时,输入的浮点值都会出现循环,而且循环输出的结果为什么都为“小孩”呢?
#7
veikin2010-10-21 11:36
回复 3楼 myth_feng
谢谢啦,不过我使用fflush(stdin)函数在循环内部,可是结果还是一样的?
#8
veikin2010-10-21 11:38
回复 5楼 书中叶
呵呵,不过我最想了解的是,输入浮点数,为什么会出现循环.
#9
hoho5682010-10-21 14:15
以下是引用veikin在2010-10-21 11:34:48的发言:

是呀,将year 改为double型以后就正常,但是我很好奇的就是为什么year设置为整形时,输入的浮点值都会出现循环,而且循环输出的结果为什么都为“小孩”呢?
问题1:为什么每次循环输出的结果都是小孩[color=#000000],并不是这样的,不然你输入一个比较大的数字(浮点型),会得到不同的答案,这和你输入的数值的大小有关系,但是可以确定的一点就是循环的结果一直是一个。就是一直为小孩,中年,或者老年。
问题2:为什么会产生循环;[/color]你会发现当你将year改为浮点型时,就不会出现循环了。我认为的原因是这样的(并不一定正确),以为你一开始对整型变量输入了浮点型数据,所以你的cin输入流发生错误,就已经不再执行了,缓冲区里一直存放着你一开始存放的数据,所以一直是你第一个输入的数,因此就产生了一个死循环。
3楼的解决方法是对的,就是每次清空你的输入流缓冲区,这样就保证的一次输入数据流出错不会引起死循环。

补充的一点:通常情况下,当一个输出流cout执行时,输入流cin里面的缓冲就会清空的,可能因为你的cin输入流出现错误,所以缓冲区没有清空,同时也不再接受新的数据吧。。

#10
veikin2010-10-21 14:58
回复 9楼 hoho568
很感谢你的回答,不过我还是有些疑问。
①我测试过输入值:0<year<131之间浮点数值时,它能够进入while循环中,但是输出的值都为:“小孩”,或许是相当于不同的PC机访问同一个内存地址,所获得的值不一样那样等待道理(我猜的)。
②三楼那个方法我也尝试过了,不过我运行的 结果还是一样,麻烦你帮我看一下,谢谢。。。程序如下:
#include<iostream.h>
#include "stdio.h"

void main()
{
    int year,i;
    cout<<"year=";
    cin>>year;
    if(year<0)
        cout<<"input error!"<<endl;
    while(year>=0 && year<=130)
    {
        i=year/10;
        switch(i)
        {
        case 0:
            cout<<"小孩"<<endl;
            break;
        case 1:
            cout<<"少年"<<endl;
            break;
        case 2:
            cout<<"青年"<<endl;
            break;
        case 3:
        case 4:
            cout<<"中年"<<endl;
            break;
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
            cout<<"老年"<<endl;
            break;
        default:
            cout<<"input error!"<<endl;
        }
        fflush(stdin);
        cout<<"input year=";
        cin>>year;
    }
}
#11
无名可用2010-10-21 15:16
      输入的数据先放在缓冲区中,当输入结束时再由‘cin流’从缓冲区将第一个类型的正确数据取走。如果输入浮点数,假如你输入45.6,‘cin流’会把整数部分45从缓冲区取走,此时缓冲区还剩下的数据为.6(因为缓冲区还有数据存在,所以就暂时不用人为的从键盘输入数据了,直到cin流把缓冲区中的数据全部取走),当进入循环时,cin流无法再从缓冲区取走数据了,所以变量i也就无法再被重新赋值了,所以输出就会一直是‘青年’或其他程序也因cin流不断的在取数据而进入了无限循环中..
程序代码:
[color=#0000FF]#include<iostream>
using namespace std;

void main()
{
        int year,i;
        cout<<"year=";
        cin>>year;
        if(year<0)
                cout<<"input error!"<<endl;
        while(year>=0 && year<=130)
        {
                ///
                if(cin.fail())
                {
                    cout<<"输入有误"<<endl;
                    cin.clear();
                    double d;
                    cin>>d;
                }
                cout<<"请重新输入,year=";
                cin>>year;
                ///
                i=year/10;
                switch(i)
                {
                case 0:
                        cout<<"小孩"<<endl;
                        break;
                case 1:
                        cout<<"少年"<<endl;
                        break;
                case 2:
                        cout<<"青年"<<endl;
                        break;
                case 3:
                case 4:
                        cout<<"中年"<<endl;
                        break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                        cout<<"老年"<<endl;
                        break;
                default:
                        cout<<"input error!"<<endl;
                }
                cout<<"input year=";
                cin>>year;
        }
}


[/color]
#12
hoho5682010-10-21 15:17
以下是引用veikin在2010-10-21 14:58:08的发言:

很感谢你的回答,不过我还是有些疑问。
①我测试过输入值:0<131之间浮点数值时,它能够进入while循环中,但是输出的值都为:“小孩”,或许是相当于不同的PC机访问同一个内存地址,所获得的值不一样那样等待道理(我猜的)。
②三楼那个方法我也尝试过了,不过我运行的 结果还是一样,麻烦你帮我看一下,谢谢。。。程序如下:
#include
#include "stdio.h"

void main()
{
    int year,i;
    cout<<"year=";
    cin>>year;
    if(year<0)
        cout<<"input error!"<
    while(year>=0 && year<=130)
    {
        i=year/10;
        switch(i)
        {
        case 0:
            cout<<"小孩"<
            break;
        case 1:
            cout<<"少年"<
            break;
        case 2:
            cout<<"青年"<
            break;
        case 3:
        case 4:
            cout<<"中年"<
            break;
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
            cout<<"老年"<
            break;
        default:
            cout<<"input error!"<
        }
        fflush(stdin);
        cout<<"input year=";
        cin>>year;
    }
}
我运行了你的程序,发现没有问题啊。输出不会都是小孩,而且也不再进入循环;
我的程序和你的唯一区别可能是在头部
#include<iostream>

using namespace std;

其他函数体一样。我的环境 visual studio 2010 ;
#13
veikin2010-10-21 17:01
回复 11楼 无名可用
但是我还是有一点疑问,就是假设我输入45.6的话,那它第一次从缓存中取出的是45,然后再进入死循环,那么它第一次显示的应该是“老年”,但是我输入区间在(0-131)直接输出值都是“小孩”的。
#14
veikin2010-10-21 17:04
回复 12楼 hoho568
我用你说的,但是一样出现循环,我的环境是visual c++6.0
#15
brightboy2010-10-21 18:27
  当你把cout<<"input year=";  cin>>year;去掉时,你就会发现 这个函数是一直循环的 比如你要是输入100则一直是老年..当你输入错误值时,就会一直是 year=小孩,其实 不管你输入多大的数,只要不是int型的,就一直是year=小孩.你输入 一个字符时也一样,因为你输入错误 他直接给跳到case(0)了。。。。
#16
veikin2010-10-21 20:47
回复 15楼 brightboy
把cout<<"input year=";  cin>>year;去掉时,因为while语句中并没对year值进行修改,所以当然输入100就会进入死循环。不过我想应该就是你说的这样,只要输错,就直接跳到case 0...3Q啦。。。
#17
Tveiker2010-10-22 01:46
当你定义year为整形但输入为浮点型时,cin只会截取year整数部分放入流中,而不会截取小数部分。故当为小数时应该处理这个
下面就是代码并有解释
#include<iostream.h>
#include "stdio.h"

void main()
{//将整数和小数作为两种类型来写
    cout<<"请输入你所输入数的类型:"<<endl
        <<"0---整数:"<<endl   //0代表整数
        <<"1---小数:"<<endl;  //1代表小数
    int t;
    cin>>t;  //t不能再year后面输入,读到后面的解释你就会明白
    /*
    看到这里你一定会问为什么不直接用year判断。原因就是year是整型数据故向year输入的一定是整数,故怎么判断都只会是整数
    至于小数部分只是没有放入cin流中
    */
    int year;
    int i;
    cout<<"year=";
    cin>>year;
    if(year<0)
        cout<<"input error!"<<endl;
    while(year>=0 && year<=130)
    {
        i=year/10;
        switch(i)
        {
        case 0:
            cout<<"小孩"<<endl;
            break;
        case 1:
            cout<<"少年"<<endl;
            break;
        case 2:
            cout<<"青年"<<endl;
            break;
        case 3:
        case 4:
            cout<<"中年"<<endl;
            break;
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
            cout<<"老年"<<endl;
            break;
        default:
            cout<<"input error!"<<endl;
        }
        if(t){
            //如果是小数则就应想办法将其小数部分放入cin流中
            cin.ignore();//跳过小数点
            cin>>year;  //将小数点后的数放入cin流
        }
        //在此时对于上一个year已经全部处理完了,进行新的一次
        cout<<endl<<"请输入你所输入数的类型:"<<endl<<"0---整数:"<<endl<<"1---小数:"<<endl;
        cin>>t;
        cout<<"input year=";
        cin>>year;
    }
}
#18
Tveiker2010-10-22 01:55
回复 13楼 veikin
之所以以后一直输出小孩是因为小数点没处理那么就相当于里面仍有非数据的东西,而此时小数点后面的数是6,其<10的数,即每次输入的year就会是6。则i=0;
#19
Tveiker2010-10-22 02:18
以下是引用Tveiker在2010-10-22 01:55:35的发言:

之所以以后一直输出小孩是因为小数点没处理那么就相当于里面仍有非数据的东西,而此时小数点后面的数是6,其<10的数,即每次输入的year就会是6。则i=0;
这里纠正下,调试可以发现,当小数点没处理时,year是0,为什么呢?建议楼主稍微思考下,但当小数点被处理后那么year就会变成小数点后面的数,此时要用cin>>year处理
然后再输入自己第二次想输入的值
     在这里我想建议楼主编完程后多调试,编译器其实是学好编程最好的老师
       至于year为什么在小数点没处理时为0,其实此时就相当你输入了一个0.XX(XX为原year的小数部分),那么再次cin>>year,截取整数部分0
#20
veikin2010-10-22 09:28
回复 19楼 Tveiker
很感谢19楼,可能是太浮躁了最近,没能静下来好好的调试一下。。。
#21
veikin2010-10-22 11:50
回复 19楼 Tveiker
我用编译器调试了,不过调试结果是year值都为小数点前面那个数,并不是小数部分。
#22
Tveiker2010-10-22 22:56
回复 21楼 veikin
当程序运行到cin.ignore()后,year还是小数点前面的那个整数?
但是我的调试却是我说的那个结果
只是我不知道这个怎么插图,不然就给你了
也许是编译器的差异
1