Thomas Eding
Thomas Eding

Reputation: 1

C++ stream get unget not a nop?

I have the following C++ program and ran it using Visual Studio 2008 on Windows 7. I get and then unget a character. After doing so, the file position is different. Why? How do I get around this problem?


test.txt (download link below if you want)

/* Comment 1 */

/* Comment 2 */

#include <fstream>

int main (int argc, char ** argv) {
    char const * file = "test.txt";
    std::fstream fs(file, std::ios::in);
    std::streampos const before = fs.tellg();

    // replacing the following two lines with
    // char c = fs.peek(); results in the same problem
    char const c = fs.get();
    fs.unget();

    std::streampos const after = fs.tellg();
    fs.seekg(after);
    char const c2 = fs.get();
    fs.close();
    return 0;
}

Adding | std::fstream::binary to the constructor seems to solve the problem. Perhaps it has to do with newlines in the file? If so, why does it affect code that doesn't even get close to reading a newline?

Updated with a seeking to the after position and getting another character.

It seems that saving via Notepad vs. Vim makes a difference. Saving via Notepad makes the stream work okay.

I have uploaded the file to google docs if you want to dl it:

https://docs.google.com/leaf?id=0B8Ufd7Rk6dvHZmYyZjgwYmItMTI3MC00MDljLWJjYTctMWMxYWM0ODk1MTE2&hl=en_US

Upvotes: 2

Views: 378

Answers (2)

JoeFish
JoeFish

Reputation: 3100

Ok using your input file I see the same behavior you do. After some experimentation, it looks like the file was in Unix format, then had the ^M characters edited out (at least that's how I was able to reproduce it).

To fix it, I edited the file in Vim, executed ":set ff=dos", then added and deleted a character to dirty the file, then saved it.

Upvotes: 2

mloskot
mloskot

Reputation: 38940

The file position behaves as expected:

// unget.cpp
#include <fstream>
#include <iostream>
int main ()
{
    char const * file = "test.txt";
    std::fstream fs(file, std::fstream::in);

    std::cout << fs.tellg() << std::endl; // 0
    char c = fs.get();
    std::cout << fs.tellg() << std::endl; // 1
    fs.unget();
    std::cout << fs.tellg() << std::endl; // 0

    fs.close();
    return 0;
}

Build and run:

$ clang++ unget.cpp 
$ ./a.out 
0
1
0

Or, I don't understand where is the problem.

Upvotes: 0

Related Questions