2
#include <iostream>
#include <sstream>
#include <fstream>

using namespace std;

int main(){

    fstream input("EX17.39file.txt", fstream::ate | fstream::out | fstream::in);

    if(!input){
        cout << "Failed to open file. Exiting." << endl;
        return EXIT_FAILURE;
    }

    auto end_mark = input.tellp();
    input.seekg(0, fstream::beg);

    for(string line; getline(input, line);){

        auto read_mark = input.tellg();

        input.seekp(0, fstream::end);
        input.seekg(read_mark);

        char c;
        while(input >> c)
        cout << c << " ";

    }


}

All the inside of the while loop really does is move from the current position to the end, and then back to the current position. Then it outputs each character left in the stream. Except for an input file of something like:

abcd
efg
//newline

My output is

f g

I find it odd that e got missed. If I move the part of the loop which outputs the rest of the stream before the input.seekp(0, fstream::end); command, i.e.

for(string line; getline(input, line);){

        auto read_mark = input.tellg();

        char c;
        while(input >> c)
        cout << c << " ";

        input.clear();
        cout << endl;

        input.seekp(0, fstream::end);
        input.seekg(read_mark);     

}

then e f g gets output like normal. So when the stream gets placed to the end, and then back to its original position, for some reason it isn't placed in the correct position and misses e?

If I change everything from an fstream to a stringstream:

stringstream input("abcd\nefg\n", fstream::ate | fstream::out | fstream::in);

Then it outputs like I expect.

Why is seekg(read_mark) not bringing it back to its original position? (mingw64 gcc 5.2.0).

Edit: input.tellg() before the move and input.tellg() after the move both output the same value of 7.

SergeantPenguin
  • 843
  • 7
  • 16
  • This could be a compiler bug with your version. I compiled it exactly as you wrote in the first example, save for changing `EXIT_FAILURE`, and it prints "e f g". My GCC-G++ is 4.9.2 on MSYS2. –  Dec 18 '15 at 19:21
  • 1
    Does your file have 2 bytes `\r` `\n` for end-of-line? Does opening it in binary mode solve the problem? I don't have the answer but I think these two points are very important to clear up. – anatolyg Dec 18 '15 at 20:05
  • @anatolyg Actually yes, `fstream::binary` makes it work and the output is `e f g` (although I'm not totally sure what it does). As for your first query, how would I check that? I just pressed enter. – SergeantPenguin Dec 18 '15 at 20:09
  • 1
    This reminds me a time when a program of mine was crashing when parsing a 400 KB XML file. After an excruciating debug session I finally found that the base64 strings in the file contained isolated `\n` bytes, while the rest of the file used the normal Windows `\r\n` linebreaks. I still wonder what sort of library could have generated such a mostruosity. – Alberto M Dec 18 '15 at 20:28
  • @SergeantPenguin: open the file in a hex editor. A text editor would usually regularize the newlines on the fly when you open the file, hindering you by finding the error. – Alberto M Dec 18 '15 at 20:31
  • @Alberto @anatolyg Okay thanks. Yeah there are two bytes for end of line (`\r\n`). Specifically `61 62 63 64 0D 0A 65 66 67 0D 0A`. – SergeantPenguin Dec 18 '15 at 20:43
  • 1
    Found a duplicate question with full answer: http://stackoverflow.com/questions/27055771/using-seekg-in-text-mode . Seems you actually hit a compiler bug. – Alberto M Dec 18 '15 at 20:57
  • @AlbertoM Compiler bugs will be the death of me. Thanks. – SergeantPenguin Dec 19 '15 at 20:38

0 Answers0