【问题标题】:Getting the stream position where failbit was set / std::ios::failure was thrown获取设置失败位/抛出 std::ios::failure 的流位置
【发布时间】:2017-10-29 15:48:30
【问题描述】:

我需要解析一个文件并获取失败位置(如果有)。问题是如果设置了failbittellg() 将毫无用处。

是否有一种优雅的(内置的?)方法可以找到设置failbit 的位置?

更新

使用clear()tellg()是否有效?我找不到流的状态(包括位置)是否保证在失败后保持有效

【问题讨论】:

  • clear失败后,您可以继续从失败点读取流,因此必须保留位置。当解析器再次尝试读取无法解析的数据时,这有时会导致另一次失败。您必须以某种方式删除不良/意外数据。典型解决方案ignore 一个令牌长度或切换到不同的解析状态以查找不同的数据。

标签: c++ stream position


【解决方案1】:

您只需要clear 流,就可以使用tellg()

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>

int main()
{
    std::ifstream infile("input.txt");

    std::vector<int> data{ std::istream_iterator<int>(infile), {} };

    infile.clear();
    std::cout << "failed at position: " << infile.tellg();
}

当然,这仅适用于支持tellg(有意义)的流。例如,如果您尝试将它与std::cin 一起使用而不是fstream,您将不会得到有意义的结果(使用我测试过的编译器返回-1,但我没有确定这是保证)。

【讨论】:

    【解决方案2】:

    如果在处理异常时流已经超出范围,则不可行。如果流仍在范围内,您可以clear 故障位,然后,如果需要,使用setstate 重置故障位。

    例子:

    #include <iostream>
    #include <sstream>
    
    int main()
    {
        std::stringstream test("10 20 thirty 40 50");
        test.exceptions(std::istream::failbit);
    
        try
        {
            int val;
            while (test >> val)
            {
    
            }
        }
        catch (...)
        {
            std::cout << "Went boom.\n";
        }
        test.clear();
        std::cout << test.tellg();
        // test.setstate(std::ios::failbit);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      • 2013-03-09
      • 2023-01-04
      • 1970-01-01
      相关资源
      最近更新 更多