第八章有个例子,非常简单,就是读入用户输入,赋给一个int,这里面有一个判断,就是如果用户输入的不是int,那么,cin就会变成invalid,里面就有condition state,于是我们可以catch这个state并clear,然后继续读入。
但是书上给的例子有个错误,原来的程序是这样的:
这里有两个错误:
(1)在Linux,g++环境下,cin.clear(istream::failbit)并不能清除cin的fail状态,尽管从clear函数的文档上来看应该是可以的。没办法,我改成了cin.clear()就OK了
(2) 遗漏了cin.ignore这个句子或有相同效果的代码。这是因为cin的fail状态虽然被消除了,但是本次读入的错误的用户输入,比如用户输入的是一 个字符串,还存在于cin的buffer中,这样,下次循环cin >> ival照样出错,于是这样就形成了死循环。因为cin的buffer中始终存在着用户第一次输入的错误数据,于是while循环就一直继续着。
后 来我加了这样一句: cin.ignore(100000, '\n'); 就OK了。可以看ignore的文档,代码的意思是ignore buffer中从一开始到第一个\n为止的所有字符,第一个参数故意写的很大,这是因为ignore的第一个参数表示ignore多少个字符,太小会导致 buffer中清除的不干净。
修改后的代码如下:
顺便附上本章的另外一个练习代码,打印文本内容,使用了fstream:
但是书上给的例子有个错误,原来的程序是这样的:
- Code: Select all
#include <iostream>
#include <stdexcept>
using namespace std;
int main(int argc, char **argv)
{
int ival;
// cout << "Begin state is: " << cin.rdstate() << endl;
while (cin >> ival, !cin.eof()) {
// cout << "Current Enter loop state is: " << cin.rdstate() << endl;
if (cin.bad()) {
// no catch so the terminate will be called
throw runtime_error("IO Stream corrupted");
}
if (cin.fail()) {
cerr << "bad data, try again: ";
cin.clear(istream::failbit);
// cout << "Current state is: " << cin.rdstate() << endl;
continue;
}
// ok, print out this integer
cout << "Input correct, your number is: " << ival << endl;
}
}
这里有两个错误:
(1)在Linux,g++环境下,cin.clear(istream::failbit)并不能清除cin的fail状态,尽管从clear函数的文档上来看应该是可以的。没办法,我改成了cin.clear()就OK了
(2) 遗漏了cin.ignore这个句子或有相同效果的代码。这是因为cin的fail状态虽然被消除了,但是本次读入的错误的用户输入,比如用户输入的是一 个字符串,还存在于cin的buffer中,这样,下次循环cin >> ival照样出错,于是这样就形成了死循环。因为cin的buffer中始终存在着用户第一次输入的错误数据,于是while循环就一直继续着。
后 来我加了这样一句: cin.ignore(100000, '\n'); 就OK了。可以看ignore的文档,代码的意思是ignore buffer中从一开始到第一个\n为止的所有字符,第一个参数故意写的很大,这是因为ignore的第一个参数表示ignore多少个字符,太小会导致 buffer中清除的不干净。
修改后的代码如下:
- Code: Select all
#include <iostream>
#include <stdexcept>
using namespace std;
int main(int argc, char **argv)
{
int ival;
// cout << "Begin state is: " << cin.rdstate() << endl;
while (cin >> ival, !cin.eof()) {
// cout << "Current Enter loop state is: " << cin.rdstate() << endl;
if (cin.bad()) {
// no catch so the terminate will be called
throw runtime_error("IO Stream corrupted");
}
if (cin.fail()) {
cerr << "bad data, try again: ";
cin.clear();
// Here cin's error condition state cannot be removed unless
// we use cin.clear() directly
// cin.clear(istream::failbit);
// ignore current read wrong characters otherwise the loop
// will go infinitely
cin.ignore(11111111, '\n');
// cout << "Current state is: " << cin.rdstate() << endl;
continue;
}
// ok, print out this integer
cout << "Input correct, your number is: " << ival << endl;
}
}
顺便附上本章的另外一个练习代码,打印文本内容,使用了fstream:
- Code: Select all
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
ifstream input;
vector<string> filelist;
filelist.push_back("read.cc");
filelist.push_back("fread.cc");
filelist.push_back("dummy.cc");
vector<string>::const_iterator it = filelist.begin();
string s;
// loop begin
while (it != filelist.end()) {
input.open(it->c_str());
if (!input) {
cout << "Open file " << *it << " failed, quit..." << endl;
break;
}
cout << "Printing file " << *it << endl;
while (getline(input, s))
cout << s << endl;
input.close();
input.clear();
++it;
}
}