How to read a file twice (e.g. like an old two-pass assembler do) using std::ifstream
?
I tried the obvious
#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, compiling with GCC 4.9.2 on Linux/x86-64/Debian
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With