Search code examples
c++binaryfstream

How to correctly input binary from a file


I am trying to make a hex editor and I want to read from a file. I am using fsteam for this. I am still not very familiar to this library, so I am not sure what I did wrong.

What I am trying to do is to read the first 8 bits(1 byte) of the file as binary and then convert it into hex and display it. My problem is that I am not sure how to get the 8 bits. The code bellow fills the char array with the first char of the file ("H").

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;


int main()
{
    string path = "c:/users/sjames/desktop/s.txt";
    vector<char> buffer(1, 0);

    fstream file;
    file.open(path, ios::binary | ios::in);
    if (file.is_open())
    {
        file.read(&buffer[0], buffer.size());
        for (int i = 0; i < buffer.size(); i++)
        {
            cout << buffer[i, 0] << endl;
        }
        file.close();
    }
    return 0;
}

Solution

  • I want to read 8 bits or 1 byte. And I want to input it in binary.

    So, then simply read() 1 byte. The code you have shown is read()'ing 8 bytes instead. A char is 1 byte, and you are creating a vector with 8 chars in it.

    Try this instead:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    int main()
    {
        string path = "c:/users/sjames/desktop/s.txt";
        unsigned char b;
    
        ifstream file(path, ios::binary);
        if (file.is_open())
        {
            if (file.read(reinterpret_cast<char*>(&b), 1))
                cout << hex << setw(2) << setfill('0') << static_cast<unsigned short>(b) << endl;
            file.close();
        }
        return 0;
    }
    

    Which you can then expand on to display multiple bytes as needed:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iomanip>
    using namespace std;
    
    int main()
    {
        string path = "c:/users/sjames/desktop/s.txt";
        vector<unsigned char> buffer(...); // TODO: query the file's size, perhaps...
    
        ifstream file(path, ios::binary);
        if (file.is_open())
        {
            if (file.read(reinterpret_cast<char*>(buffer.data()), buffer.size()))
            {
                size_t numRead = file.gcount();
                for (size_t i = 0; i < numRead; ++i)
                {
                    cout << hex << setw(2) << setfill('0') << static_cast<unsigned short>(buffer[i]) << endl;
                }
                file.close();
            }
        }
        return 0;
    }
    

    FYI, notice the type-casts to unsigned short when using operator<<. This is because std::ostream has overloaded operator<<](https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2) to treat [(un)signed] char values as text], not as numbers. So, if you want to print out a char as a number, even in hex format, you need a cast the char to a non-char numeric type.