What is wrong with this code for reading binary files?


What is wrong with this code for reading binary files? It compiles OK, but
will not print out the file as planned.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>

int main(int argc, const char *argv[])
{
   if (argc < 2) {
      ::std::cerr << "usage: " << argv[0] << " <filename>\n";
      return 1;
   }
   ::std::basic_ifstream<unsigned char> in(argv[1], ::std::ios::binary);
   unsigned char uc;
   while (in.get(uc)) {
      printf("%02X ", uc);
   }
   // TODO: error handling, in case the file could not be opened or read
   return 0;
}


Changing to char and then casting to unsigned char works.

Maybe one the experts here can say why unsigned char didn't work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>

int main(int argc, const char *argv[])
{
   if (argc < 2) {
      ::std::cerr << "usage: " << argv[0] << " <filename>\n";
      return 1;
   }
   ::std::basic_ifstream<char> in(argv[1], ::std::ios::binary); /// char
   char uc; /// char
   while (in.get(uc)) {
      printf("%02X ", (unsigned char) uc); /// cast to unsigned char
   }
   // TODO: error handling, in case the file could not be opened or read
   return 0;
}
Last edited on
In the case of the first code, it shouldn't compile. There is no overload of get which takes a reference to unsigned char.

http://stackoverflow.com/questions/436513/char-signed-char-char-unsigned-char

Furthermore, the %X format specifier for printf tells printf that you're feeding it an unsigned int type. If you're feeding it a char as in the original code the argument will be promoted to an int, which is not an unsigned int. If you're feeding it an unsigned char as in vin's code, it will be promoted to an unsigned int which is the correct type. I do believe I would be a little more explicit in the casting, though: printf("%02X ", (unsigned)uc);.

Edit: Of course the C++ way of doing this is less prone to error.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <sstream>

int main()
{
    std::istringstream in("Humpty Dumpty");

    char ch;
    while (in.get(ch))
        std::cout << std::hex << static_cast<unsigned>(ch) << ' ';
}


http://ideone.com/aWbkKx
Last edited on
Topic archived. No new replies allowed.