【问题标题】:reading a C++ ifstream twice?读取 C++ ifstream 两次?
【发布时间】:2015-03-06 15:19:09
【问题描述】:

如何使用std::ifstream 读取文件两次(例如,像旧的两遍汇编器那样)?

我尝试了显而易见的

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

int main(int argc, char**argv)
{
  std::string path = argc>1?std::string{argv[1]}:std::string(__FILE__);
  std::ifstream inp{path};
  int num=0;
  std::cout << "first pass" << std::endl;
  do {
    std::string lin;
    std::getline(inp,lin);
    if (inp.eof())
      break;
    num++;
    std::cout << "#" << num << ":" << lin << std::endl;
  } while (!inp.eof());
  inp.seekg(0, inp.beg);
  inp.sync();
  std::cout << "second pass" << std::endl;
  num=0;
  do {
    std::string lin;
    std::getline(inp,lin);
    if (inp.eof())
      break;
    num++;
    std::cout << "##" << num << ":" << lin << std::endl;
  } while (!inp.eof());
  inp.close();
  return 0;
}  

它不起作用(第二个循环无限循环)。

FWIW,在 Linux/x86-64/Debian 上使用 GCC 4.9.2 编译

精度

实际上,我正在尝试解析一个文件,该文件由以下行组成...)。我需要一个两遍算法。第一步是提取所有名称(如somename)并构建一些“空”命名的东西。第二遍是从它们后面的 JSON 对象中填充命名的东西。 JSON 解析是使用最近的 1.5 jsoncpp 库完成的。

【问题讨论】:

  • 清除不良标志可能是? inp.clear();
  • “第二个循环无限循环”并打印什么?..
  • 几个月前我就有这个问题了,看我的问答stackoverflow.com/questions/28331017/…
  • 您不应该使用ifstream::eof() 来控制阅读循环。您应该使用文件读取操作来控制循环。这样一旦读取失败,循环就会停止。

标签: c++ linux c++11


【解决方案1】:

最后一次调用std::getline 在到达流结束时失败,设置failbit。由于设置了failbit,因此对seekg 的调用无效。在调用seekg (DEMO) 之前,您需要clear 流的状态标志:

namespace {
void one_pass(std::istream& is) {
  std::string lin;
  for (int num = 0; std::getline(is, lin); ++num) {
    std::cout << '#' << num << ':' << lin << '\n';
  }
}
} // unnamed namespace

int main(int argc, char**argv)
{
  std::ifstream inp{argc > 1 ? argv[1] : __FILE__};

  std::cout << "first pass\n";
  one_pass(inp);

  inp.clear();
  inp.seekg(0);

  std::cout << "\nsecond pass\n";
  one_pass(inp);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 2013-09-19
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多