I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):
#include <cctype> #include <cstdlib> #include <algorithm> #include <iostream> #include <iterator> #include <ostream> #include <stdexcept> #include <string> #include <vector> template <typename OutputIt> class hex_ostream_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> { OutputIt out; int digitCount; int number; public: hex_ostream_iterator(OutputIt out) : out(out), digitCount(0), number(0) { } hex_ostream_iterator<OutputIt> & operator=(char c) { number = (number << 4) | char2int(c); digitCount++; if (digitCount == 2) { digitCount = 0; *out++ = number; number = 0; } return *this; } hex_ostream_iterator<OutputIt> & operator*() { return *this; } hex_ostream_iterator<OutputIt> & operator++() { return *this; } hex_ostream_iterator<OutputIt> & operator++(int) { return *this; } private: int char2int(char c) { static const std::string HEX_CHARS = "0123456789abcdef"; const char lowerC = std::tolower(c); const std::string::size_type pos = HEX_CHARS.find_first_of(lowerC); if (pos == std::string::npos) { throw std::runtime_error(std::string("Not a hex digit: ") + c); } return pos; } }; template <typename OutputIt> hex_ostream_iterator<OutputIt> hex_iterator(OutputIt out) { return hex_ostream_iterator<OutputIt>(out); } template <typename InputIt, typename OutputIt> hex_ostream_iterator<OutputIt> from_hex_string(InputIt first, InputIt last, OutputIt out) { if (std::distance(first, last) % 2 == 1) { *out = '0'; ++out; } return std::copy(first, last, out); } int main(int argc, char *argv[]) { if (argc != 2) { std::cout << "Usage: " << argv[0] << " hexstring" << std::endl; return EXIT_FAILURE; } const std::string input = argv[1]; std::vector<unsigned char> bytes; from_hex_string(input.begin(), input.end(), hex_iterator(std::back_inserter(bytes))); typedef std::ostream_iterator<unsigned char> osit; std::copy(bytes.begin(), bytes.end(), osit(std::cout)); return EXIT_SUCCESS; }
And the output of ./hex2bytes 61a062a063 | hexdump -C:
00000000 61 a0 62 a0 63 |a.b.c| 00000005
And of ./hex2bytes 6a062a063 | hexdump -C (note odd number of characters):
00000000 06 a0 62 a0 63 |..b.c| 00000005