1

I read a file with std::ifstream into an std::vector< char >, and would like to print each char as a hexadecimal value. I can do this with printf but would prefer to do it with std::cout in an elegant way:

std::ifstream ifs( "myfile", std::ios::binary | std::ios::ate );
std::ifstream::pos_type pos = ifs.tellg();
std::vector< char > buffer( pos );
ifs.seekg( 0, std::ios::beg );
ifs.read( buffer.data(), pos );
// File contents loaded perfectly

printf( "%02hhx", buffer[ 1234 ] );
// Prints what I want but not modern C++

std::cout << std::hex << std::fill( '0' ) << std::setw( 2 ) << buffer[ 1234 ];
// Modern C++ but does not print what I want (e.g. if `buffer[ 1234 ]` is 65, an A appears)

std::cout << std::hex << std::fill( '0' ) << std::setw( 2 )
          << static_cast< int >( *reinterpret_cast< const unsigned char* >( &buffer[ 1234 ] ) );
// Modern C++ and prints what I want. But what about neatness and elegance?
user4581301
  • 33,082
  • 7
  • 33
  • 54
z32a7ul
  • 3,695
  • 3
  • 21
  • 45
  • Your last example is way overkill. Just `static_cast(static_cast(buffer[1234]))` would suffice. You can create a simple function `int asint(char)` for that if you really think it's ugly. If you want to treat the file as binary data, I suggest reading it into `std::vector` or `std::vector` instead, which makes the unsigned-cast unnecessary. – paddy Apr 02 '20 at 07:11
  • no need for such an ugly cast. Just [use a unary plus `<< +buffer[ 1234 ]`](https://stackoverflow.com/q/14365732/995714) – phuclv Apr 02 '20 at 07:15
  • @phuclv: That's an interesting idea. Unfortunately, it would prefix negative numbers with ffffff. – z32a7ul Apr 02 '20 at 07:24
  • @paddy If I change my vector's type to uint8_t, then I get this error: invalid conversion from ‘unsigned char*’ to ‘std::basic_istream::char_type* {aka char*}’. Looks like I have to modify the ifstream somehow. I tried `std::ifstream< uint8_t > ifs( ... )` but it gives an error: ‘std::ifstream {aka std::basic_ifstream}’ is not a template – z32a7ul Apr 02 '20 at 07:32
  • @z32a7ul that's implementation-defined behavior. `char` is not necessarily signed a. You can change to unsigned char with a switch. [Is char signed or unsigned by default?](https://stackoverflow.com/q/2054939/995714) – phuclv Apr 02 '20 at 07:52

0 Answers0