请大家看看我这个程序错在哪?

erlaio 2008-06-26 08:59:17
#include <iostream>
程序为C++ primer 4th 8章的程序,但是输入 字母 循环不会中止 怎么回事??


#include <stdexcept>
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof()){
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail()){
cerr<<"bad data, try again";
cin.clear(istream::failbit);
continue;
}
cout<<ival<<endl;
}
return 0;
}
...全文
214 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
K行天下 2008-06-26
  • 打赏
  • 举报
回复
在解释一下为什么单用
cin.clear(istream::failbit);
不行:
流有3个状态,对应于3个定义的位标志stream::iostate:

stream::badbit
系统级的故障,如无法恢复的读写错误,流通常无法继续使用。
stream::failbit
可恢复的流错误,如在希望获得数值型的数据时输入了字符,
stream::eofbit
文件结束,同时还会设置failbit标志
有3个操作bad(), fail(), eof()分别用于测试以上的标志,流状态是否正常可以用good()来测试;流的状态字可以由rdstate()读出;另外还有两个操作用于改变流的状态:clear()和setstate(),但它们的操作结果不怎么符合我们的直觉。
关键是:
setstate必须有个一个表示流状态的参数,操作结果将使指定的状态位置位(set),其他的状态位不变,无法作reset操作。clear用于设置流的状态为参数指定的状态字,它实际上是个set操作,而不是reset,它的参数有一个默认的值为goodbit,这实际是个0,不带参数调用时就是clear状态,带参数时,并不是我们想象中的reset参数指定的位,而是将整个状态字设置成参数指定的那样。

所以你单用
cin.clear(istream::failbit);
是不行的:
可以这样做:
cin.clear(istream::failbit ^ cin.rdstate());

但是图方便的话,
直接用cin.clear();就行了


K行天下 2008-06-26
  • 打赏
  • 举报
回复
不好意思,我上面的说错了

// 一定要放到cerr前面,否则没法清除

可以放到前面,只是之前我用了楼主的cin.clear(istream::failbit); 达不到目的!
K行天下 2008-06-26
  • 打赏
  • 举报
回复

#include <stdexcept>
#include <iostream>
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof())
{
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail())
{
cin.clear();
cin.ignore();//因为没有清空输入流,下次循环还是 字母
cerr <<"bad data, try again:"<<endl; // 一定要放到cerr前面,否则没法清除
continue;
}
cout <<ival <<endl;
}
system("PAUSE");
return 0;
}


erlaio 2008-06-26
  • 打赏
  • 举报
回复
谢谢 各位高人,期待高人能写个 C++ primer 4th 的勘误 对我们初学者由用
K行天下 2008-06-26
  • 打赏
  • 举报
回复

#include <stdexcept>
#include <iostream>
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof())
{
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail())
{
cin.clear();
while(cin.get()!='\n');
cerr <<"bad data, try again";
continue;
}
cout <<ival <<endl;
}
system("PAUSE");
return 0;
}


K行天下 2008-06-26
  • 打赏
  • 举报
回复

#include <stdexcept>
#include <iostream>
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof())
{
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail())
{
cin.clear();
while(cin.get()!='\n');
cerr <<"bad data, try again";
continue;
}
cout <<ival <<endl;
}
system("PAUSE");
return 0;
}


K行天下 2008-06-26
  • 打赏
  • 举报
回复

#include <stdexcept>
#include <iostream>
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof())
{
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail())
{
cin.clear();
while(cin.get()!='\n');
cerr <<"bad data, try again";
continue;
}
cout <<ival <<endl;
}
system("PAUSE");
return 0;
}


xjy1204 2008-06-26
  • 打赏
  • 举报
回复
#include <stdexcept> 
using namespace std;

int main()
{
int ival;
while(cin>>ival, !cin.eof()){
if(cin.bad())
throw runtime_error("IO stream corrupted");
if(cin.fail()){
cerr <<"bad data, try again" <<endl;
cin.clear();
cin.ignore();
continue;
}
cout <<ival <<endl;
}
return 0;
}
hai040 2008-06-26
  • 打赏
  • 举报
回复
上面的判断写错了,应该直接判断
cin.rdstate() == ios_base::failbit
hai040 2008-06-26
  • 打赏
  • 举报
回复
http://blog.csdn.net/daineng/archive/2008/04/05/2252730.aspx
clear(state)实际上是set(state),即cin.rdstate = state

cin.clear(ios_base::failbit);
cout<<((cin.rdstate() & ios_base::failbit) == ios_base::failbit);


另外,输入的字符也还在缓冲里
在continue前要调用cin.sync()清空缓冲
allen0001 2008-06-26
  • 打赏
  • 举报
回复
重新输入。。不晓得了。。。。等待高人
allen0001 2008-06-26
  • 打赏
  • 举报
回复
阿,刚没看懂,把continue改为break好像就行了
erlaio 2008-06-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 allen0001 的回复:]
改为char ival;
[/Quote]

只输入 int 的数字, 如果遇到字母重新输入, 改为char 不行吧
allen0001 2008-06-26
  • 打赏
  • 举报
回复
改为char ival;
erlaio 2008-06-26
  • 打赏
  • 举报
回复
怎样修改呢?

[Quote=引用 1 楼 babyvox1999 的回复:]
因为这个

C/C++ code
while(cin>>ival, !cin.eof())
[/Quote]
babyvox1999 2008-06-26
  • 打赏
  • 举报
回复
因为这个

while(cin>>ival, !cin.eof())

65,179

社区成员

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

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