| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2437 人关注过本帖
标题:c++的标准输入流测试循环问题
取消只看楼主 加入收藏
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
结帖率:50%
收藏
 问题点数:0 回复次数:5 
c++的标准输入流测试循环问题
在老外的C++教程里面一般都会介绍一个标准输入流的条件测试cin>>num;把它作为循环条件的时候可以用来测试文件尾,但我目前发现的问题是这个条件的失败情况并不是遇到了回车换行符,而是读取数据失败的情况,也就是说如果把测试函数写成这样的话:

int mai()

{

             int  num=0,

                    sum=0;

             while(cin>>num)

                      sum+=num;

              cout<<"total is:"<<sum<<endl;

             return 0;

}

如果仅仅一次输入1 2 3 4的话就会出现无限循环的情况,回车之后根本不是传说中的文件尾测试,而是数据读取测试,必须在后面加上一个非int类型的数据才算读取失败,也就是说必须输入1 2 3 4y这样的数据才能结束循环输出总和,然而新的问题成为了:我如何控制那些非int类型数据的缓冲读入。我尝试改变测试代码如下:

int main()

{

          int  num=0,

                   sum=0;

          char  c;        //用于记录最开始的非int字符

          char  arr[10]="bad";

          while(cin>>num)

                  sum+=num;

          cin>>c;            //

          cin>>arr;          //添加的测试

          cout<<"total is:"<<sum<<endl;

          cout<<c<<endl;

          cout<<arr<<endl;

          return 0;

}

我使用了VC++6.0和gcc(sgywin)测试了代码,结果是添加的4行代码直接被那个循环屏蔽了,添加的那两行代码根本无效,用调试器也是,直接不用输入就一路给步过了。我输入了1 2 3 4ygood,然后输出是:

total is:10

                                        //空行是因为字符变量c定义的同时被gcc初始化了

bad

把那个循环封装到函数里面但从那个位置插入调用也是一样的效果,请问各位大虾为何?
搜索更多相关主题的帖子: 输入 
2009-08-01 11:18
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 2楼 sadan20111
你这个可太夸张!完全连文件尾都不能测试了!一般来说,同时按下控制键和Z代表的是windows文件的文件尾,我这边调试你的程序好像会直接卡住,你在你的机器上看看输入文件尾能不能跳出循环。你要知道所有的输入都是字符,你把字符串变量当做测试对象,当然不能跳出循环了,输入的数字也算字符的。要不你改改,像我这样用提取符就可以跳出循环了。
2009-08-01 18:27
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 5楼 sadan20111
我不是分析了我自己的程序嘛。首先是读取,读取的时候程序测试cin的读取状态,如果读取成功那么标志流是可用的,那么会通过条件测试,如果读取失败,那么流被标记为错误的,条件测试就会失败,那么就会跳出循环。
在人机交互的时候,一切键盘输入都是字符,你用字符串做参数读取行就意味着不可能会发生读取失败的情况,因为每次都会读取以整行字符串,所以,只能使用文件尾来使流的读取失败,但是我这边用文件尾测试你的代码会直接卡住,可能是我的系统有错误,不知道你的状况是什么样子呢?
2009-08-01 21:47
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
这个返回的就是cin本身,不信你可以写这样的代码编译看看:getline(cin,line)>>other_num;它会输入两次的。
今天我用linux系统编译了一下,确实可以使用文件尾跳出循环,在linux下的文件尾是控制键+d。
这里我想可能是系统原因吧,盗版的windows不知道被删掉了哪些文件,搞不好是由于某个链接库被删掉了导致无法识别文件尾或者删除不完全,导致可以识别文件尾但没有相关文件而使行为成了未定义的。
2009-08-02 11:03
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 10楼 东方罗密欧
如果我没理解错误的话,足下的意思是:当输入流被标记错误状态,那么输入流的缓冲区将被冻结,由于输入流的输入机制是当按下回车换行符时,从缓冲区的第一个位置指针扫描,扫描到回车换行符之前的字符,然后将回车换行符流在了缓冲区,故而,当数据被冻结时,直接会跳过错误的数据而读入回车换行符,于是输入读入了空字符(据我所知gets函数不能连用就是因为会读入空字符串)。但是尊兄细看,如果是这样的机制,那么我在cin>>arr这行就应该会重置arr的数据才对,因为它读入了空字符串,但实际上,它并没有重置——它没有被改动过——应该是说此时的输入流无效才对。
另外,如果刷新了输入流,我原来在数字字符尾输入的字符串何去何从呢?望启发童蒙。
2009-08-02 18:03
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 9楼 sadan20111
VISTA还正版不正版的- -|
但看有没有微软授权徽标就知道了,反正我的XP是盗版,最近不知道那个文件又损坏了,整个系统慢得不好说啥。
另外,你如果在用VISTA并且在用VC++6.0的话建议你还是用兼容模式,好多人都说VC和VISTA不兼容的。
2009-08-02 18:07
快速回复:c++的标准输入流测试循环问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017035 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved