Search code examples
c++fstream

std::fstream::tellg() outputs file cursor pointer incorrectly?


I have a std::fstream, which I imported using

std::fstream myFile { "C:/path/to/file.txt" };

When I want to read the first byte, I use

char c;
cout << myFile.tellg() << endl; // Correctly outputs 0 (begining of file)
myFile.read(&c, 1);
cout << myFile.tellg() << endl; // Should output 1, but it outputs
                                // FFFFFFFFFFFFFFFA
myFile.read(&c, 1);
cout << myFile.tellg() << endl; // Should output 2, but it outputs
                                // FFFFFFFFFFFFFFFB

What's happening here?

I tried putting

midi_file.seekg(0, ios_base::beg);

or

midi_file.seekg(0, myFile.beg);

But the cursor moves to FFFFFFFFFFFFFFFA whenever I try to read a byte.

EDIT:

I don't know if it has something to do, but I did an endianness test and these are the results:

bool endianness = *reinterpret_cast<short*>("10") & 1; // Outputs 1

EDIT 2:

The file is broken, as the output is not the same with another file, but why is it?

Here is the byte data from the file, taken from HxD, which is a .midi file:

4D 54 68 64 00 00 00 06 00 01 00 03 00 04 4D 54
72 6B 00 00 00 A1 00 C0 69 00 90 3C 5A 01 41 5A
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01 
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01 
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 00 00 FF 2F 00 4D 54 72 6B 00 00 00 41 00 
C1 72 05 91 3C 5A 00 40 5A 00 43 5A 00 48 5A 0A 
35 5A 00 41 5A 00 44 5A 00 49 5A 0A 37 5A 00 40 
5A 00 43 5A 00 48 5A 0A 41 5A 00 47 5A 0A 30 5A 
00 40 5A 00 43 5A 00 48 5A 05 32 00 00 FF 2F 00 
4D 54 72 6B 00 00 00 26 00 C2 47 0A 92 50 64 01 
52 64 09 50 78 00 52 78 0A 50 00 01 52 00 09 50 
78 01 50 00 0A 52 00 00 50 00 00 FF 2F 00

EDIT 3:

Here is the full code of this test:

#include <fstream>
#include <iostream>

int main() {
    cout << std::hex << std::setfill('0') << std::uppercase;

    fstream midi_file{ "D:/Descargas/OutFile.midi" };

    cout << midi_file.good() << endl; // Outputs 1

    char c;
    cout << midi_file.tellg() << endl; // Correctly outputs 0 (begining of file)
    midi_file.read(&c, 1);
    cout << midi_file.tellg() << endl; // Erroneously outputs FFFFFFFFFFFFFFFA
    midi_file.read(&c, 1);
    cout << midi_file.tellg() << endl; // Erroneously outputs FFFFFFFFFFFFFFFB

    // Endianness test:
    cout << (*reinterpret_cast<short*>("10") & 1) << endl; // Outputs 1

    return 0;
}

Solution

  • File open mode must be in ios::binary mode not to catch special characters.