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

时间:2021-01-06 19:40:52
#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;
}

16 个解决方案

#1


因为这个

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

#2


怎样修改呢?

引用 1 楼 babyvox1999 的回复:
因为这个 

C/C++ code
while(cin>>ival, !cin.eof())

#3


改为char ival; 

#4


引用 3 楼 allen0001 的回复:
改为char ival; 


只输入 int 的数字, 如果遇到字母重新输入, 改为char 不行吧

#5


阿,刚没看懂,把continue改为break好像就行了

#6


重新输入。。不晓得了。。。。等待高人

#7


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()清空缓冲

#8


上面的判断写错了,应该直接判断
cin.rdstate() == ios_base::failbit

#9


#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; 
}

#10



#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; 
}


#11



#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; 
}


#12



#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; 
}


#13


谢谢 各位高人,期待高人能写个 C++ primer 4th 的勘误 对我们初学者由用

#14



#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; 
}


#15


不好意思,我上面的说错了

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

可以放到前面,只是之前我用了楼主的cin.clear(istream::failbit); 达不到目的!

#16


在解释一下为什么单用
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();就行了


#1


因为这个

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

#2


怎样修改呢?

引用 1 楼 babyvox1999 的回复:
因为这个 

C/C++ code
while(cin>>ival, !cin.eof())

#3


改为char ival; 

#4


引用 3 楼 allen0001 的回复:
改为char ival; 


只输入 int 的数字, 如果遇到字母重新输入, 改为char 不行吧

#5


阿,刚没看懂,把continue改为break好像就行了

#6


重新输入。。不晓得了。。。。等待高人

#7


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()清空缓冲

#8


上面的判断写错了,应该直接判断
cin.rdstate() == ios_base::failbit

#9


#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; 
}

#10



#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; 
}


#11



#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; 
}


#12



#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; 
}


#13


谢谢 各位高人,期待高人能写个 C++ primer 4th 的勘误 对我们初学者由用

#14



#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; 
}


#15


不好意思,我上面的说错了

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

可以放到前面,只是之前我用了楼主的cin.clear(istream::failbit); 达不到目的!

#16


在解释一下为什么单用
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();就行了