如何使用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
库完成。
答案 0 :(得分:3)
在到达流末尾时对std::getline
的最后一次调用失败,设置为failbit
。自failbit
设置后,对seekg
的调用无效。在调用seekg
(clear
)之前,您需要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);
}