使用getline()而不设置failbit

Use getline() without setting failbit

本文关键字:设置 failbit getline 使用      更新时间:2023-10-16

是否可以使用getline()读取有效文件而不设置failbit ?我想使用failbit,以便在输入文件不可读时生成异常。

下面的代码总是输出basic_ios::clear作为最后一行—即使指定了有效的输入。

test.cc:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
    ifstream inf;
    string line;
    inf.exceptions(ifstream::failbit);
    try {
        inf.open(argv[1]);
        while(getline(inf,line))
            cout << line << endl;
        inf.close();
    } catch(ifstream::failure e) {
        cout << e.what() << endl;
    }
}

input.txt:

the first line
the second line
the last line

结果:

$ ./a.out input.txt 
the first line
the second line
the last line
basic_ios::clear

你不能。标准规定getline:

如果函数没有提取字符,它调用is.setstate(ios_base::failbit),可能抛出ios_base::failure(27.5.5.4)。

如果你的文件以空行结束,即最后一个字符是'n',那么最后一次调用getline不读取字符并失败。实际上,如果不设置failbit,您希望如何终止循环呢?while的条件总是为真,它将永远运行。

我认为你误解了failbit的意思。不是表示不能读取文件。它被用作最后一次操作成功的标志。badbit用于指示低级故障,但它对标准文件流几乎没有用处。Failbit和eofbit通常不应被解释为异常情况。另一方面,badbit应该,我认为fstream::open应该设置badbit而不是failbit。 无论如何,上面的代码应该写成:
try {
    ifstream inf(argv[1]);
    if(!inf) throw SomeError("Cannot open file", argv[1]);
    string line;
    while(getline(inf,line))
        cout << line << endl;
    inf.close();
} catch(const std::exception& e) {
    cout << e.what() << endl;
}