std::getline does not stop at eof

I'm trying to read the content of a file using std::getline but this function seems to corrupt the object since it tries to read after the eof and then becomes impossible to write in that file.

Here is the minimal code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  int main() {
    
    std::fstream saveFile;
    saveFile.open("save.txt", std::ios::in | std::ios::out );
    if(!saveFile.is_open()) std::cerr<<"file not open\n"; //file opens perfectly
    std::string line;

    while (std::getline(saveFile,line)) ;
    if(saveFile.fail()) std::cerr<<"getline error\n"; //I get this error

    line = "++ IMG prova ++\n";
    saveFile<<line; //nothing get written
    saveFile.seekg(0,saveFile.end);
    long size = saveFile.tellg();
    std::cerr<<"size of saveFile "<<size; //size is -1
    saveFile.close();
}


Thanks for helping.
You have an empty read loop:
1
2
3
4
5
6
7
8
9
10
    std::string line;

    while (std::getline(saveFile,line)) 
        ; // empty loop      
        
    std::cout << std::boolalpha;
    std::cout << "good: " << saveFile.good() << '\n'           
              << "bad:  " << saveFile.bad()  << '\n'           
              << "fail: " << saveFile.fail() << '\n'           
              << "eof:  " << saveFile.eof()  << '\n';

Expected Output:
good: false
bad:  false
fail: true
eof:  true


That is the normal state of affairs since while (getline() ) will loop until the fail() condition occurs.

Before the file can be used again, the flags must be cleared:
 
    saveFile.clear(); 


I am aware of the empty loop (that was only the minimal code which would show my problem).

Inserting saveFile.clear(); before writing solved the problem.

Thanks a lot
Inserting saveFile.clear(); before writing solved the problem.

Really? Supposing you have a file like this:
line 1
line 2
line 3
line 4
line 5

Slightly modifying your code to make it compile, I get:
line 1
line++ IMG prova ++
4
l++ IMG prova ++


Perhaps I’ve misinterpreted your code or that is the desired output - if so, please ignore the rest of the post.

If I’m not misinterpreting your code, there could be other issues.
You are reading and writing at the same time on one file, but your file position indicator is moved by both operation, since that indicator is shared between those operations.
https://stackoverflow.com/questions/15670359/fstream-seekg-seekp-and-write
You can try to figure out how your file position indicator moves just printing its value on screen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <fstream>
#include <iostream>
#include <string>

void waitForEnter();

int main()
{
    std::fstream saveFile;
    saveFile.open("save.txt", std::ios::in | std::ios::out );
    if(!saveFile.is_open()) { 
        std::cerr << "file not opened\n";
        return 1;
    }
    std::string line;
    while (std::getline(saveFile,line)) {
        std::cout << "You are reading at position " << saveFile.tellg() << '\n';
        if(saveFile.fail()) { 
            std::cerr << "getline error\n"; 
            return 1;
        }
        line = "++ IMG prova ++\n";
        std::cout << "You are writing at position " << saveFile.tellp() << '\n';
        saveFile << line;
    }
    saveFile.seekg(0);
    auto size = saveFile.tellg(); // tellg() returns std::ifstream::pos_type
    std::cerr << "size of saveFile: " << size;
    saveFile.close();
    waitForEnter();
    return 0;
}

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

You are reading at position 12
You are writing at position 12
You are reading at position 33
You are writing at position 33
size of saveFile: -1
Press ENTER to continue...

Following the solution suggested in the above post could be complicated, but you could read from one file and write to an other one, like a temporary one, and then substitute the latter for the former once you’ve done.

P.s. if you are working on images, maybe you want to open your files in binary mode.
Topic archived. No new replies allowed.