读两次C ++ ifstream?

时间:2015-03-06 15:19:09

标签: c++ linux c++11

如何使用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对象,然后是一些空的换行符(并且可能再次重复一次** someothername后跟另一个JSON对象等...)。我需要一个双程算法。第一遍是提取所有名称(如somename)并构建一些“空”命名的东西。第二遍是从它们后面的JSON对象填充命名的东西。 JSON解析使用最近的1.5 jsoncpp库完成。

1 个答案:

答案 0 :(得分:3)

在到达流末尾时对std::getline的最后一次调用失败,设置为failbit。自failbit设置后,对seekg的调用无效。在调用seekgclear)之前,您需要DEMO流的状态标记:

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