Dev Notes

Software Development Resources by David Egan.

Display char as Hexadecimal String in C++


C++
David Egan

Displaying a char or a collection of chars as a hexadecimal string in C++ is surprisingly tricky.

For context, let’s say you are collecting bytes from /dev/urandom in a std::vector and you need to display them to the user:


#include <iostream>
#include <fstream>
#include <vector>
#include <fstream>
#include <iterator>
#include <iomanip>

int main()
{

  int n = 0;
  std::cout << "Enter the number of random bytes to fetch from /dev/urandom:" << '\n';
  if (!(std::cin >> n)) {
  	std::cout << "Not an integer. Exiting..." << '\n';
  	return 1;	
  }
  std::ifstream file("/dev/urandom", std::ios::binary|std::ios::in);
  if (!file) {
  	std::cerr << "Couldn't open /dev/urandom. Exiting..." << '\n';
  	return 1;
  }
  std::vector<char> randomBytes(n);
  file.read(&randomBytes[0], n);

  // Displaying bytes: method 1
  // --------------------------
  for (auto& el : randomBytes)
  	std::cout << std::setfill('0') << std::setw(2) << std::hex << (0xff & (unsigned int)el);
  std::cout << '\n';

  // Displaying bytes: method 2
  // --------------------------
  for (auto& el : randomBytes)
  	printf("%02hhx", el);
  std::cout << '\n';
  return 0;
}

Method One: std::cout

Method 1 as shown above is probably the more C++ way:

  • Cast to an unsigned int
  • Use std::hex to represent the value as hexadecimal digits
  • Use std::setw and std::setfill from <iomanip> to format

Note that you need to mask the cast int against 0xff to display the least significant byte: (0xff & (unsigned int)el).

Otherwise, if the highest bit is set the cast will result in the three most significant bytes being set to ff.

Method 2: printf()

Method 2 uses the printf() function with the "%02hhx" format string.

This is pretty much C style code. It’s quite a bit shorter though!


comments powered by Disqus