Search code examples
c++debuggingfstream

fstream produces REALLY weird behavior


When I write a double to a filestream, then write an integer, the integer gets appended to the double as extra digits, and I have no idea why it happens. Could someone please explain this for me? Minimal example:

#include <iostream>
#include <fstream>

int main()
{
    std::fstream s("test.bin", std::fstream::binary | std::fstream::trunc | std::fstream::in | std::fstream::out);
    s << 3.14;
    int n = 36;
    s << n;
    s.seekp(0);
    double d;
    s >> d;
    printf("%f\n", d);
}

What I expect to happen:

  • The program opens a file called test.bin
  • It writes the value 3.14 to the file (8 bytes)
  • It writes the value 36 to the file (4 bytes)
  • It skips back to the beginning of the buffer
  • It reads a double-type value (8 bytes)
  • It prints the value (displaying 3.140000)

What actually happens: The program outputs 3.143600 - I have absolutely no idea why this happens. It makes zero sense. If I change the initial value, say from 3.14 to 18.3204, then it outputs 18.320436. What's happening?


Solution

  • It writes the value 3.14 to the file (8 bytes)
    It writes the value 36 to the file (4 bytes)

    This is not what happens. >> and << and friends read and write values in human-readable form.

    s << 3.14; writes the digit 3, a full stop, the digit 1, and the digit 4 to the file (4 ASCII characters). s << 36; writes the digit 3, and the digit 6 to the file (2 ASCII characters).

    The file then contains 6 ASCII characters: a 3, a full stop, a 1, a 4, a 3, and a 6. Or as any normal person would write it: it contains 3.1436.

    s >> d; reads a number, by characters from the file until it finds a character that doesn't look like a number, and then converting the characters it read into a number (the same way they'd be converted if you typed them into cin). It reads 3, full stop, 1, 4, 3, 6, and then produces the number 3.1436.