Using fstream :: seekg under windows in a file created under Unix

I have a C ++ cross-platform program (compiled with g ++ on Linux and with Visual Studio on PC). This program writes lines to a text file (using the <<and operator std::endl), but can also read data from the generated text file (using std::getline).

To optimize access to data and save memory when reading a data file, I read it for the first time and saved the position of the data in my program. When data is needed, I later use it seekgto go to a specific position and read the data.

  • Creating and reading a file on a PC works great.
  • Creating and reading a file on Linux works great.
  • But creating the file on Linux and reading on the PC fails.

Under PC, the search call sometimes cannot move the cursor accordingly. I could highlight the problem in the example below. It reads the file once, saves the second line and value, then returns to the saved position and reads the line again.

#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>
int main()
{
    std::fstream file;
    file.open( "buglines.txt", std::ios_base::in );
    if ( file.is_open() )
    {
        std::streampos posLine2;
        std::string lineStr;
        std::string line2Str;
        int line = 1;
        while ( std::getline( file, lineStr ) )
        {
            if ( line == 1 )
                posLine2 = file.tellg(); // save line 2 position
            if ( line == 2 )
                line2Str = lineStr; // save line 2 content

            ++line;
            std::cout << lineStr <<std::endl;
        }
        std::cout << "Reached EOF, trying to read line 2 a second time" << std::endl;
        file.clear(); // clear EOF flag
        file.seekg(posLine2); // move to line 2
        std::getline( file, lineStr ); // read the line
        assert( lineStr == line2Str ); // compare

    }
    return 0;
}

I am running this from windows.

  • If it buglines.txtwas created under Windows (the hex editor shows line breaks as 2 characters 0x0D 0x0A), it works ( lineStr == line2Str).
  • If it buglines.txtwas created under Linux (the hex editor shows line 0x0Abreaks as 1 character ), it does not work (line Str is an empty line). Even if the getline loop worked fine.

I know that both systems work differently with EOL, but since I just use the getlineread function , I was hoping it would work smart ... did I miss something?

+2
1

, -, "".

std::ios_base::binary . , : \r getline.

, - , : , , n , :

#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>

int main()
{
    std::fstream file;
    const std::string fileName = "buglines.txt";
    file.open( fileName.c_str(), std::ios_base::in );
    if ( file.is_open() )
    {
        std::streampos posLine2;
        std::string lineStr;
        std::string line2Str;
        int line = 1;
        while ( std::getline( file, lineStr ) )
        {
            if ( line == 1 )
                posLine2 = file.tellg(); // save line 2 position
            if ( line == 2 )
                line2Str = lineStr; // save line 2 content

            ++line;
            std::cout << lineStr << std::endl;
        }
        std::cout << "Reached EOF, trying to read line 2 a second time" << std::endl;
        //file.clear(); // clear EOF flag
        //file.seekg(posLine2); // move to line 2
        file.close();
        file.open( fileName.c_str(), std::ios_base::in );
        assert( file.is_open() );
        char* temp = new char[static_cast<int>(posLine2)+1];
        file.read( temp, static_cast<int>(posLine2)+1 ); // if posLine2 is too big, consider splitting with in a loop
        delete [] temp;
        assert( file.tellg() == posLine2 );

        std::getline( file, lineStr ); // read the line
        assert( lineStr == line2Str ); // compare
    }
    return 0;
}
0

All Articles