使用 getline() 而不设置故障位

Posted

技术标签:

【中文标题】使用 getline() 而不设置故障位【英文标题】:Use getline() without setting failbit 【发布时间】:2011-12-12 21:41:00 【问题描述】:

是否可以在不设置failbit 的情况下使用getline() 读取有效文件?我想使用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;
    

输入.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() 时您预计何时会引发故障位? 如果文件不存在。例如./a.out nosuchfile.txt 打开文件后可以查看is_open()。 我刚碰到这个。在我看来,它应该设置 eofbit,而不是 failbit。烦人。 【参考方案1】:

你不能。该标准说getline

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

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

我认为您误解了 failbit 的含义。它确实 not 意味着无法读取该文件。它被用作最后一次操作成功的标志。为了指示低级故障,使用了 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;

【讨论】:

感谢您解释failbit 限制。您的实施有效。

以上是关于使用 getline() 而不设置故障位的主要内容,如果未能解决你的问题,请参考以下文章

使用 cin.getline() 和 cin.get()

cin.get() 和 cin.getline() 之间的区别

cin, getline() 与 get() 的区别

get()与getline()

转 cincin.get()cin.getline()getline()gets()等函数的用法

C++基础:各种输入方法总结,cincin.get()cin.getline()getline()gets()getchar()