什么是缺陷?
对于C++代码来说,编译、链接、运行与你所想像的结果不一样
Stream的缺陷例子:
list<int> a; while (!cin.eof()) { int x; cin >> x; if (!cin.eof()) a.push_back(x); }缺陷:
while (!cin.eof()) { // ... }这样有可能是一个死循环. 如果流的状态不转变成fail, 流将永远无法到达文件尾部。一个最典型的例子是建立一个没有任何数据的空文件,然后去读,使用eof()函数作为判断文件结束的条件,那么就会陷入死循环。
例子:
ofstream foo_out("foo.txt");
if(!foo_out.is_open()){
return false;
}
foo_out.close();
ifstream foo_in("foo.txt");
string read_content; while (!readline(foo_in, read_content).eof()) {
// 处理代码,这里有可能陷入死循环,当foo.txt是空文件的时候,死循环就会出现
} 所以,当读取数据时, 如果已经无法读取你所要类型的数据,流的状态应该被设为fail。
教训: 在寻找文件结束标识EOF时,eof() 函数仅仅在与fail()结合在一起使用才会发挥其作用。
例子:
while (cin.good()) { int x; cin >> x; if (cin.good()) a.push_back(x); }缺陷:
cin >> x; // <--- 有可以读取成功,然后遇到EOF if (cin.good()) a.push_back(x);如果文件结束行直接后面跟EOF,以上代码有可能读不到最后一个元素。
修正: 使用fail():
while (!cin.fail()) { int x; cin >> x; if (!cin.fail()) a.push_back(x); } 类型从basic_ios转换到void* 同样为!fail():
while (cin) { int x; cin >> x; if (cin) a.push_back(x); }Moral: 下面的流函数中: good(), bad(), eof(), and fail(). (注意 bad() 并不意味着!good().) 仅仅只有一个函数如你想像一样使用: fail().