getline设置failbit以及eof [英] getline setting failbit along with eof

查看:84
本文介绍了getline设置failbit以及eof的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这种行为的起源,因为在SO的多个帖子中已经对此进行了很好的解释,一些著名的例子是:

I am aware of the origin of this behavior since it has been very well explained in multiple posts here in SO, some notable examples are:

为什么在循环条件内考虑iostream :: eof错误吗?

使用getline()而不设置failbit

std :: getline抛出当它达到eof

C ++ istream EOF不能保证故障位吗?

并且它也包含在 std :: getline 标准:

And it is also included in the std::getline standard:

3)如果出于任何原因(甚至没有丢弃的定界符)都没有提取任何字符,则getline设置failbit并返回.

3) If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.

我的问题是如何处理这种行为,在这种情况下,您希望流在所有情况下都捕获一个 failbit 异常,但由于到达 eof 而导致的异常除外,最后一行为空的文件的片段.有什么明显的我想念的东西吗?

My question is how does one deal with this behavior, where you want your stream to catch a failbit exception for all cases except the one caused by reaching the eof, of a file with an empty last line. Is there something obvious that I am missing?

MWE:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>


void f(const std::string & file_name, char comment) {

std::ifstream file(file_name);
file.exceptions(file.failbit);
    try {
          std::string line;

          while (std::getline(file, line).good()) {
          // empty getline sets failbit throwing an exception
            if ((line[0] != comment) && (line.size() != 0)) {
                std::stringstream ss(line);
                // do stuff
            }
        }
    }

    catch (const std::ios_base::failure& e) {
        std::cerr << "Caught an ios_base::failure.\n"
        << "Explanatory string: " << e.what() << '\n'
        << "Error code: " << e.code() << '\n';

        }
}


int main() {

    f("example.txt", '#');
}

其中 example.txt 是制表符分隔的文件,最后一行仅是 \ n char:

where example.txt is a tab-delimited file, with its last line being only the \n char:

# This is a text file meant for testing
0   9
1   8
2   7

while(std :: getline(file,line).good()){...} 复制了问题.

推荐答案

另一种避免设置 failbit 的方法,只是重构您的 if 测试以检测读取的内容.空行.由于在这种情况下这是您的最后一行,因此您可以简单地 return 以避免引发错误,例如:

Another way to avoid setting failbit, is simply to refactor your if tests to detect the read of an empty-line. Since that is your final line in this case, you can simply return to avoid throwing the error, e.g.:

    std::ifstream file (file_name);
    file.exceptions (file.failbit);
    try {
        std::string line;

        while (std::getline(file, line)) {
            // detect empty line and return
            if (line.size() == 0)
                return;
            if (line[0] != comment) {
                std::stringstream ss(line);
                // do stuff
            }
        }
    }
    ...

您的另一种选择是检查是否在 catch 中设置了 eofbit .如果设置了 eofbit -读取成功完成.例如

You other alternative is to check whether eofbit is set in catch. If eofbit is set -- the read completed successfully. E.g.

    catch (const std::ios_base::failure& e) {
        if (!file.eof())
            std::cerr << "Caught an ios_base::failure.\n"
            << "Explanatory string: " << e.what() << '\n'
            << "Error code: " /* << e.code() */ << '\n';
    }

这篇关于getline设置failbit以及eof的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆