C++:关于cin输入ctrl+Z之后不能再用问题的原因
哈哈哈,我又来了。
今天写一个需要两次循环输入的程序的时候,出现了一个问题。先贴代码:
#include<iostream> #include<string> #include<vector> #include<stdexcept> using std::cout; using std::cin; using std::endl; using std::cerr; using std::string; using std::vector; using std::out_of_range; int CalcInt(vector<string> vecStr) { int i,sum; for(i = 0,sum = 0;i!=vecStr.size();++i) { sum += stoi(vecStr.at(i)); } return sum; } double CalcDou(vector<string> vecStr) { int i; double sum = 0.0; for(i = 0;i != vecStr.size();++i) { sum += stod(vecStr.at(i)); } return sum; } int main() { vector<string> vecStr; string str; while(cin>>str) { vecStr.push_back(str); } try{ cout<<CalcInt(vecStr)<<endl; } catch(out_of_range err) { cout<<err.what()<<endl; cout<<"转换整型失败!"<<endl; } vecStr.clear(); while(cin>>str) { vecStr.push_back(str); } try{ cout<<CalcDou(vecStr)<<endl; } catch(out_of_range err) { cout<<err.what()<<endl; cout<<"转换整型失败!"<<endl; } return 0; }
代码执行如下:
在我敲完Ctrl+Z并键下回车后,直接出现270和0。然而有代码可知我本来的意思并非如此,本意是想要在输出一次之后,在进行一次输出。
可是好像第二次的输入直接失败了,还不等我有任何的输入。
思考了一下,猜想是否是cin的状态位被置为0,导致cin不能输入,强行输入强掳灰飞烟灭,导致输入失败。所以在后面的while输入循环前,加了个cin.clear();对cin标志位进行复位。
代码如下:
#include<iostream> #include<string> #include<vector> #include<stdexcept> using std::cout; using std::cin; using std::endl; using std::cerr; using std::string; using std::vector; using std::out_of_range; int CalcInt(vector<string> vecStr) { int i,sum; for(i = 0,sum = 0;i!=vecStr.size();++i) { sum += stoi(vecStr.at(i)); } return sum; } double CalcDou(vector<string> vecStr) { int i; double sum = 0.0; for(i = 0;i != vecStr.size();++i) { sum += stod(vecStr.at(i)); } return sum; } int main() { vector<string> vecStr; string str; while(cin>>str) { vecStr.push_back(str); } try{ cout<<CalcInt(vecStr)<<endl; } catch(out_of_range err) { cout<<err.what()<<endl; cout<<"转换整型失败!"<<endl; } vecStr.clear(); cin.clear(); while(cin>>str) { vecStr.push_back(str); } try{ cout<<CalcDou(vecStr)<<endl; } catch(out_of_range err) { cout<<err.what()<<endl; cout<<"转换整型失败!"<<endl; } return 0; }
其结果如下:
成功了!
既然这样了,仔细解释一下原理:
其实在《C++Primer5E》8.1.2中对IO条件状态有着仔细地解释,但是书上讲的多,而且有些东西讲的比较分散,所以有些东西我总结在这里:
1.IO操作一个与生俱来的问题就是可能发生错误。一些错误可恢复,而其他错误发生在系统深处,超出应用程序可以修正的范围。故而IO类有定义一些函数和标志,可以帮助我们访问和操纵流的条件状态。具体条件状态可以百度查看。
2.cin中的条件状态表示主要有四个标志位,badbit,failbit,eofbit,goodbit。其中,badbit在流崩溃的情况下被置位,failbit在IO操作失败的情况下被置位,eofbit在流达到文件结束的时候被置位,goodbit为0表示流未处于错误状态,当goodbit为0时流为有效状态,而另外三个标志位任何一个被置位都将导致流错误。clear()函数将流复位,状态置为有效。
3.Ctrl+Z表示文件结束符,当cin读到时,则eofbit和failbit都被置位。此时流处于无效状态。
4.一个流一旦发生错误,其上的后续的IO操作都会失败。
以上就是原理的概述。