两次阅读C ++ ifstream吗? [英] reading a C++ ifstream twice?

查看:88
本文介绍了两次阅读C ++ ifstream吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How to read a file twice (e.g. like an old two-pass assembler do) using 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;
}  

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

and it does not work (the second loop is looping indefinitely).

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

FWIW, compiling with GCC 4.9.2 on Linux/x86-64/Debian

实际上,我正在尝试解析由 ** somename 等行组成的文件,其后(在下一行中)是JSON对象,后面跟着一些空的换行符(然后再重复一次 ** someothername 后面跟着另一个JSON对象等)。我需要一个两遍算法。第一步是提取所有名称(例如 somename )并构建一些空命名的事物。第二遍是从命名对象后面的JSON对象填充命名的东西。 JSON解析是使用最新的1.5 jsoncpp 库完成的。

Actually I am trying to parse a file made of lines like ** somename followed (in the next lines) by a JSON object, followed by some empty newlines (and repeatedly again perhaps a ** someothername followed by another JSON object etc...). I need a two-pass algorithm. The first pass is extracting all the names (like somename) and building some "empty" named things. The second pass is filling the named things from the JSON object following them. JSON parsing is done using a recent 1.5 jsoncpp library.

推荐答案

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

The last call to std::getline upon reaching end-of-stream fails, setting failbit. Since failbit is set, the call to seekg has no effect. You need to clear the stream's status flags before calling seekg (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);
}

这篇关于两次阅读C ++ ifstream吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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