使用 getline() 而不设置失败位

发布于 2024-12-11 16:36:19 字数 896 浏览 0 评论 0原文

是否可以使用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;
    }
}

输入.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

Is it possible use getline() to read a valid file without setting failbit? I would like to use failbit so that an exception is generated if the input file is not readable.

The following code always outputs basic_ios::clear as the last line - even if a valid input is specified.

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

results:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2024-12-18 16:36:19

你不能。该标准是关于 getline 的:

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

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

我认为您误解了failbit的含义。它意味着该文件无法读取。相反,它被用作最后一次操作成功的标志。为了指示低级故障,使用 badbit,但它对于标准文件流几乎没有用处。 failbit 和 eofbit 通常不应被解释为异常情况。另一方面 badbit 应该,而且我认为 fstream::open 应该设置 badbit 而不是 failurebit。

不管怎样,上面的代码应该写成:

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;
}

You can't. The standard says about getline:

If the function extracts no characters, it calls is.setstate(ios_base::failbit) which may throw ios_base::failure (27.5.5.4).

If your file ends with an empty line, i.e. last character is '\n', then the last call to getline reads no characters and fails. Indeed, how did you want the loop to terminate if it would not set failbit? The condition of the while would always be true and it would run forever.

I think that you misunderstand what failbit means. It does not mean that the file cannot be read. It is rather used as a flag that the last operation succeeded. To indicate a low-level failure the badbit is used, but it has little use for standard file streams. failbit and eofbit usually should not be interpreted as exceptional situations. badbit on the other hand should, and I would argue that fstream::open should have set badbit instead of failbit.

Anyway, the above code should be written as:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文