1

I have a string that represents an hexadecimal number:

std::string hex = "3371";

I want to convert it to a char array:

char hex[2] {0x33, 0x71};

Is there any convenient way to do it? I can use c++11 features, if it may help.

Motivation: I need to save an integer (4 bytes), using 2 bytes char array. The way how I thought it can be done is to convert it to string using std::hex, and then convert the string to the char array, but this is the point where I cannot continue.. If there is another simple way - I would like to hear :)

Important: I can assume that the hex number is less than 0xFFFF, and a positive number.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
binyamina
  • 173
  • 1
  • 14

2 Answers2

4

Just use std::stoi():

std::string hex = "3371";
uint16_t num = std::stoi( hex, nullptr, 16 );
uint8_t array[sizeof(num)];
memcpy( array, &num, sizeof( num ) );

note order of bytes will depend of endianness of your platform. If you need network order (as shown on your example) use htons() function:

uint16_t num = htons( std::stoi( hex, nullptr, 16 ) );
Slava
  • 43,454
  • 1
  • 47
  • 90
-1

I found out a better way to convert a number to char array, as I needed. This solution works only for unsigned types!

template <typename T> bool ToByteArray(T num, unsigned char* ret, size_t size) {
  if (ret == nullptr) {
      std::cout << "Error in: " << __func__ << ": nullptr" << std::endl;
      return false;
  }
  // drop the right-most bytes and convert to new right most byte.
  for (int i = 0; i < size; i++) {
      ret[i] = (int)((num >> (24 - 8*i)) & 0xFF);
  }
  return true;
}

This is more elegant way to do it.

If you want to convert it back - you might use:

long FormatBlock(const unsigned char* arr, size_t size) {
  long num = 0;
  for (int i = 0; i < size; i++) {
      num += ((long)arr[i] << (24 - i*8));
  }
  return num;
}
binyamina
  • 173
  • 1
  • 14
  • This is really not more elegant. It does not use C++11 features (as requested in the question), it uses old C-style character arrays and pointers. Despite using a template (why?), this looks more like C code. – user23573 Nov 16 '17 at 07:32
  • 1. template is there because I wan't this function to work with every type (int, short, long, etc). 2. I agree that this is a c code, but I prefer using it because it is generic for every type. The solution which Slava gave works only for integer. – binyamina Nov 16 '17 at 08:27
  • Using c++11 features is not a must. If there is a better way to solve the problem - it doesn't matter if c++11 features are in use or not – binyamina Nov 16 '17 at 08:31
  • "I wan't this function to work with every type (int, short, long, etc)." you will get surprises with negative values. – Slava Nov 16 '17 at 13:46
  • OK, I will add: unsigned values (I will not have data with negative values) – binyamina Nov 16 '17 at 14:19