Question

I am trying to write some simple code which will read a text file but reads the first line twice. I thought this would be as simple as something like this

    std::ifstream file;
    file.open("filename", std::ios_base::in);
    std::string line;
    std::getline(file, line);
    // process line
    file.seekg(0, ios::beg);

    while (std::getline(file, line))
    {
        // process line
    }

However the seekg must fail as the first line is not processed twice. Any idea why?

PLEASE NOTE: This is not the problem I am faced with but a simplified version of it so as not to have to paste multiple classes code and multiple functions. The real problem involves a file pointer being passed to multiple functions in multiple classes. The first function may or may not be called and reads the first line of the file. The second function reads the whole file but must first call seekg to ensure we are at the beginning of the file.

I just used the code above to simplify the discussion.

Was it helpful?

Solution

Rather than seeking back to the beginning and reading the first line twice, I think I'd approach things with something like:

std::ifstream file("filename");

std::string line;

std::getline(file, line);
process(line);

do { 
    process(line);
} while (getline(file, line));

At the moment, this assumes that process doesn't modify line (but if needed, it's easy enough to make an extra copy of it for the first call).

Edit: given the modified requirements in the edited answer, it sounds like the seek is really needed. That being the case, it's probably cleanest to clear the stream before proceeding:

std::getline(file, line);
process1(line);

file.seekg(0);
file.clear();

process2(file);

OTHER TIPS

Ideally your code should look like this:

std::ifstream file("filename"); //no need of std::ios_base::in

if ( file ) //check if the file opened for reading, successfully
{
   std::string line;
   if ( !std::getline(file, line) )
   {
        std::cerr << "read error" << std::endl;
        return;
   }

   // process line

   if ( !file.seekg(0, ios::beg) )
   {
        std::cerr << "seek error" << std::endl;
        return;
   }

   while ( std::getline(file, line) )
   {
      // process line
   }
}
else
{
   std::cerr << "open error" << std::endl;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top