Search code examples
c++ifstream

ifstream::read keeps returning incorrect values


I'm trying to read a .bin file and return the hexadecimal values. It all works fine until it has to read values like "F0" or "A0". It keeps returning "fffff0" or "ffffa0". When I modify the function to return decimal values the console shows "-16" and "-96" while all other correct returned values are positive.

void reader(string input) { 
int size;
char *storage;

ifstream file(input, ios::in | ios::binary);
if (file.is_open()) {
    file.seekg(0, ios::end);
    size = file.tellg();
    storage = new char[size];
    file.seekg(0, ios::beg);
    file.read(storage, size);
    file.close();
    for (int i = 0; i < size; i++) 
    {
        cout << hex << (int)storage[i] << endl;
    }
}
else {cout << "could not open file" << endl;}
}

Solution

  • "char" is a signed value. When the top bit of char is set it represents a negative value (e.g 0x80 to 0xFF). When you cast a negative value to a different size integer the value is preserved which results in a different value in hex.

    #include <iostream>
    
    int main()
    {
        char ch = 0xF0;
        int value = ch;
        std::cout << value << std::endl;
        std::cout << std::hex << value << std::endl;
    }
    

    The above program prints "-16, fffffff0". The program is actually equivalent to:

    #include <iostream>
    
    int main()
    {
        char ch = -16;
        int value = ch;
        std::cout << value << std::endl;
        std::cout << std::hex << value << std::endl;
    }
    

    To get your intended behaviour you need to mask the value:

    #include <iostream>
    
    int main()
    {
        char ch = 0xF0;
        int value = ch & 0xFF;
        std::cout << value << std::endl;
        std::cout << std::hex << value << std::endl;
    }