0

I want to convert:

  1. A simple unsigned char [] to string

  2. Then again to unsigned char

This is my code:

// This is the original char
unsigned char data[14] = {
    0x68,0x65,0x6c,0x6c,0x6f,0x20,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
};

// This convert to string
string str(data, data + sizeof data / sizeof data[0]);

// And this convert to unsigned char again
unsigned char* val = new unsigned char[str.length() + 1];
strcpy_s(reinterpret_cast<char *>(val), str.length()+1 , str.c_str());

The problem is with the 2nd part, It wont convert the string to unsigned char like it was before. I think this img from locals in debug helps

  • 1
    It [works](http://rextester.com/DTJI63799). What's the problem, exactly? – rustyx Apr 09 '18 at 11:52
  • `val` does contain a copy of `data`. Visual Studio's debug window is just not showing it as an array. If you add `val,14` to your watch list, it will be shown as an array. – KompjoeFriek Apr 09 '18 at 11:54
  • @KompjoeFriek Thank you i saw it now, I want to use `val` somewhere and it must be exactly like `data` –  Apr 09 '18 at 12:11

1 Answers1

1

One way:

#include <string>
#include <utility>
#include <cstring>
#include <memory>
#include <cassert>

int main()
{
    // This is the original char
    unsigned char data[14] = {
        0x68,0x65,0x6c,0x6c,0x6f,0x20,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
    };

    // This convert to string
    std::string str(std::begin(data), std::end(data));

    // And this convert to unsigned char again
    auto size = std::size_t(str.length());
    auto new_data = std::make_unique<unsigned char[]>(size);
    std::memcpy(new_data.get(), str.data(), size);

    // check
    for (auto f1 = data, f2 = new_data.get(), e1 = f1 + size ; f1 != e1 ; ++f1, ++f2)
    {
        assert(*f1 == *f2);
    }
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • Can you please copy `data` to a new unsigned char in the last part ? –  Apr 09 '18 at 12:06
  • It gave me `hello computerýýýý·` in result ! weird –  Apr 09 '18 at 12:20
  • @AidenStewart remember that new_data will not be null terminated. – Richard Hodges Apr 09 '18 at 12:22
  • Since C++11 *"The returned array is null-terminated, that is, data() and c_str() perform the same function."* (from http://en.cppreference.com/w/cpp/string/basic_string/data ), so you could copy `size + 1` elements to null-terminate `new_data`. – Bob__ Apr 09 '18 at 12:42
  • @Bob__ right. But look how many characters I copied out of the string. The exact number that were copied in. You'd have to increase the value of `size` by 1 to accommodate and copy out the null terminator. – Richard Hodges Apr 09 '18 at 12:44
  • @RichardHodges But here `new_data` type isn't `unsigned char` it is `enable_if::value == 0, unique_ptr>::type` –  Apr 09 '18 at 13:37
  • @AidenStewart right. It's a smart-pointer pointing to unsigned chars which have been allocated dynamically. I did this in response to your first comment where you asked for the data to be copied to "new unsigned chars". This is just a matter of where you want to store them. Not *how* to store them - that 's the purpose of the `memcpy`. – Richard Hodges Apr 09 '18 at 13:48