1

I'm currently trying to read a file as hex value, like a hex editor do. For the explanation of the issue let's suppose I've a test.txt with a simple "Hello world" inside. I'm trying to read as hex with a program close to this following code.

#include <iostream>
#include <fstream>

int main(int argc, char* argv[]) {
        std::ifstream stream;
        stream.open("test.txt", std::ios_base::binary);
        if (!stream.bad()) {
                std::cout << std::hex;
                std::cout.width(2);

                while (!stream.eof()) {
                        unsigned char c;
                        stream >> c;
                        std::cout << static_cast<unsigned>(c) << " ";
                }
        }

        return 0;
}

As output in the terminal I got

nux@pc-lubuntu:~/repos/readingHex$ od -x test.txt 
0000000 6548 6c6c 206f 6f77 6c72 0a64
0000014
nux@pc-lubuntu:~/repos/readingHex$ ./a.out 
48 65 6c 6c 6f 77 6f 72 6c 64 64

Obviously, there's a difference of endian, but that's should be easy to correct. However, as you can see on the output log, results are different at byte 5-6 and 9-10. Do someone have any idea to fix this ?

Thank you.

Waqar
  • 8,558
  • 4
  • 35
  • 43
NuxDD
  • 25
  • 3
  • 4
    I think you are looking for [`std::noskipws`](https://en.cppreference.com/w/cpp/io/manip/skipws). Those missing bytes, `20` and `0a`, and space and line feed, correspondingly. Alternatively, use `stream.read()` to read raw bytes. – Igor Tandetnik Jul 04 '20 at 20:34
  • 1
    Don’t use formatted extractiin for binary data. – molbdnilo Jul 04 '20 at 20:57
  • 2
    Read [this](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons?r=SearchResults) about `eof`. – molbdnilo Jul 04 '20 at 21:03
  • The endian issue is only because of how you use `od`. Try this: `od -A x -t x1z -v text.txt` – Ted Lyngmo Jul 05 '20 at 06:29

1 Answers1

1

Change this to :

while (!stream.eof()) {
    unsigned char c;
    stream >> c;
    std::cout << static_cast<unsigned>(c) << " ";
}

This:

unsigned char c{};
stream >> std::noskipws;
while (stream >> c) {
    std::cout << static_cast<unsigned>(c) << " ";
}
  • std::noskipws disables skipping of whitespace.
  • Read this excellent SO post on why you shouldn't do while (!stream.eof())

Alternatively, you can use read as well:

        stream.seekg(0, stream.end);
        int length = stream.tellg();
        stream.seekg(0, stream.beg);

        std::vector<char> buffer(length);

        stream.read(&buffer[0], length);

        for (auto c : buffer) {
            std::cout << static_cast<unsigned>(c) << " ";
        }

Waqar
  • 8,558
  • 4
  • 35
  • 43