2

I have the following:

char const* code = "3D";

I need to convert this 2-digit lexical hex into a std::string, which will be a string with length of 1 (not including null terminator). I have the boost library at my disposal as well. How can I do this?

In the example above, I should have a std::string that prints "=" if properly converted.

void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • You might be able to modify this answer to suit your needs: http://stackoverflow.com/questions/1967460/c-hex-parsing#1968219 – Martin Mar 07 '12 at 23:56

4 Answers4

7

I think something on this order should work:

std::istringstream buffer("3D");
int x;

buffer >> std::hex >> x;
std::string result(1, (char)x);

std::cout << result;  // should print "="
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
4

For example, using only standard C++03:

#include <cstdlib>
#include <string>
#include <iostream>

int main() {
  char const* code = "3D";
  std::string str(1, static_cast<char>(std::strtoul(code, 0, 16)));
  std::cout << str << std::endl;
}

In a real application, you'd have to test whether the entire string has been converted (second argument to strtoul) and whether the conversion result is in the allowed range.


Here is a more elaborate example, using C++11 and Boost:

#include <string>
#include <cstddef>
#include <iostream>
#include <stdexcept>

#include <boost/numeric/conversion/cast.hpp>

template<typename T>
T parse_int(const std::string& str, int base) {
  std::size_t index = 0;
  unsigned long result = std::stoul(str, &index, base);
  if (index != str.length()) throw std::invalid_argument("Invalid argument");
  return boost::numeric_cast<T>(result);
}

int main() {
  char const* code = "3D";
  std::string str(1, parse_int<char>(code, 16));
  std::cout << str << std::endl;
}
Philipp
  • 48,066
  • 12
  • 84
  • 109
2

It's not C++ but you can still use the good old scanf:

int d;
scanf("%x", &d);

Or from a string using sscanf:

int d;
sscanf(code, "%x", &d);

And using a std::string:

int d;
sscanf(code.c_str(), "%x", &d);

For some case the C format function (scanf & printf families) are easier to use than the object-oriented equivalent.

Jaffa
  • 12,442
  • 4
  • 49
  • 101
  • Shouldn't you provide an `sscanf` example? – Nicol Bolas Mar 08 '12 at 00:00
  • 2
    scanf is EVIL, and should be avoided. – Bukes Mar 08 '12 at 00:16
  • @Geoffroy: Maybe an example that works with `std::string`? You know, that uses `c_str`? – Nicol Bolas Mar 08 '12 at 02:18
  • @Bukes why is it evil? If you know how to handle it, it works well ! And the difference is that it's shorter to write. – Jaffa Mar 08 '12 at 06:41
  • 1
    @Geoffroy - It's evil for a number of reasons. It does not handle malformed input at all, and you've no way to recognize this. Many others more distinguished than I agree - scanf is evil. http://c-faq.com/stdio/scanfprobs.html, http://stackoverflow.com/questions/456303/how-to-validate-input-using-scanf – Bukes Mar 08 '12 at 17:36
  • @Bukes I agree with these reasons, but here it's not question of user input (who will ask user to write in hexa?), then you don't have much problem :) It's evil to use it everywhere, but when you know what data you're scanning, it's not evil. – Jaffa Mar 08 '12 at 17:46
  • @Geoffory - C contains many sharp knives - and this is one of them. Frankly, there's no good reason why a C++ application should be using scanf - not with all of the robust alternatives that are available. – Bukes Mar 08 '12 at 17:52
  • @Bukes if you master your input and know you can easily do something with scanf functions, then why should you use more complex structure? It's the same for printf, if you want to do the same with C++ IO Library, it may takes a dozen of lines ! – Jaffa Mar 08 '12 at 17:54
2

In Boost release 1.50 (coming this May), you would simply write

string s;
boost::algorithm::unhex ( code, std::back_inserter (s));

Works on std::string, std::wstring, QtString, CString, etc, etc.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45