seekg() function fails

2019-01-28 18:05发布

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.

2条回答
你好瞎i
2楼-- · 2019-01-28 18:35

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);
查看更多
叛逆
3楼-- · 2019-01-28 18:38

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;
}
查看更多
登录 后发表回答