| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2437 人关注过本帖
标题:c++的标准输入流测试循环问题
只看楼主 加入收藏
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
结帖率:50%
收藏
 问题点数:0 回复次数:12 
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
sadan20111
Rank: 2
等 级:论坛游民
帖 子:29
专家分:10
注 册:2009-8-1
收藏
得分:0 
楼主,我也碰到了和你一样的问题,也刚想上来问问呢,你看我的代码:
#include   <iostream>
#include  <string>  
  
  using namespace std;  
  
  main()   
  { int i=3;
   string   line;   
  while(getline(cin,line))
  {  
  cout<<line<<endl;
  
  }
 cout<<i<<endl;
  
  
  return 0;
  }
 
 
这个程序好像是个死循环,怎么能跳出循环,执行cout<<i<<endl;这句话呢,while是以istream类对象为判断条件的,那不就是遇到结束或是无效输入就跳出循环体吗?那string中,getline不是不能忽略换行符?那回车了,为什么还跳不出来呢?怎么能跳出来啊,就是什么样子才是条件才为假的啊??
2009-08-01 13:46
sadan20111
Rank: 2
等 级:论坛游民
帖 子:29
专家分:10
注 册:2009-8-1
收藏
得分:0 
而且,我调试了你的程序,设置了断点,发现都会按理论执行,但是在cin>>c时候,是输入不进去东西的,我也不知道为什么,希望有高手可以解答...
2009-08-01 13:56
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 2楼 sadan20111
你这个可太夸张!完全连文件尾都不能测试了!一般来说,同时按下控制键和Z代表的是windows文件的文件尾,我这边调试你的程序好像会直接卡住,你在你的机器上看看输入文件尾能不能跳出循环。你要知道所有的输入都是字符,你把字符串变量当做测试对象,当然不能跳出循环了,输入的数字也算字符的。要不你改改,像我这样用提取符就可以跳出循环了。
2009-08-01 18:27
sadan20111
Rank: 2
等 级:论坛游民
帖 子:29
专家分:10
注 册:2009-8-1
收藏
得分:0 
回复 4楼 Huycwork
楼主什么意思?我有点不明白,用了文件结束符也是跳不出循环的,getline()是返回cin作为判断条件的,我也该怎么用提取符呢,你的那个程序是可以跳出程序的,我这个是怎么样都挑不出来啊??
2009-08-01 21:23
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
回复 5楼 sadan20111
我不是分析了我自己的程序嘛。首先是读取,读取的时候程序测试cin的读取状态,如果读取成功那么标志流是可用的,那么会通过条件测试,如果读取失败,那么流被标记为错误的,条件测试就会失败,那么就会跳出循环。
在人机交互的时候,一切键盘输入都是字符,你用字符串做参数读取行就意味着不可能会发生读取失败的情况,因为每次都会读取以整行字符串,所以,只能使用文件尾来使流的读取失败,但是我这边用文件尾测试你的代码会直接卡住,可能是我的系统有错误,不知道你的状况是什么样子呢?
2009-08-01 21:47
sadan20111
Rank: 2
等 级:论坛游民
帖 子:29
专家分:10
注 册:2009-8-1
收藏
得分:0 
回复 6楼 Huycwork
感谢楼主这么耐心,我是初学者,但是getline()是返回cin的读取状态的吧,是http://book.上说的,楼主看看,是一本书的电子版,然后我输入ctrl+z,就是文件尾把,也是跳不出循环的,所以我就郁闷了,不知道怎么样才能让流被标记为错误,
2009-08-01 21:53
Huycwork
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2009-7-17
收藏
得分:0 
这个返回的就是cin本身,不信你可以写这样的代码编译看看:getline(cin,line)>>other_num;它会输入两次的。
今天我用linux系统编译了一下,确实可以使用文件尾跳出循环,在linux下的文件尾是控制键+d。
这里我想可能是系统原因吧,盗版的windows不知道被删掉了哪些文件,搞不好是由于某个链接库被删掉了导致无法识别文件尾或者删除不完全,导致可以识别文件尾但没有相关文件而使行为成了未定义的。
2009-08-02 11:03
sadan20111
Rank: 2
等 级:论坛游民
帖 子:29
专家分:10
注 册:2009-8-1
收藏
得分:0 
回复 8楼 Huycwork
我用的是笔记本,应该就是正版的VISTA吧,难道VISTA和windows不一样呵呵,谢谢楼主...
2009-08-02 12:40
东方罗密欧
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2008-10-22
收藏
得分:0 
测试输入流的时候,如果输入的数据类型与制定的类型不一致,则会导致输入流的错误输入状态,并且输入流中的错误数据会保存在输入缓存区里面,如果接下来再输入字符类型数据的时候,cin直接从输入缓存区里面提取到上次输入留下的'\n',导致无法继续输入。就好比两个 gets()函数不能连着用。在while()循环后你可以使用cin.clear()函数重置输入状态~用fflush(stdin);函数刷新输入缓存,就可以输入数据了~
2009-08-02 14:05
快速回复:c++的标准输入流测试循环问题
数据加载中...
 
   



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

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