Reputation: 1727
I am working on a pet project with the libsodium library, and found that converting unsigned char * to char * was less straight forward than I imagined. Also I first was confused because the tests were passing in Release mode and only bit later I realised they were not passing in Debug mode. So I came up with the following:
std::string string_from_uchar(const unsigned char * c, unsigned long long lc)
{
unsigned char * cc = new unsigned char[lc+1] ;
std::strncpy((char *) cc, (char *) c, lc);
cc[lc] = 0;
char* cr = reinterpret_cast<char *> (cc);
std::string ret(cr);
delete[](cr);
return ret;
}
While it now passed the tests, I was be grateful if someone could check if it is the right way of doing it (for instance would that work on another environment like gcc or clang?).
Upvotes: 1
Views: 994
Reputation: 385305
You're massively over-thinking this.
The copy is redundant, as is the extra dynamic allocation and the addition of a null terminator (because std::string
has a constructor that accepts a length argument for just this sort of occasion).
The various char
can be aliased, so simply:
std::string string_from_uchar(const unsigned char * c, unsigned long long lc)
{
return std::string((const char*)c, lc);
}
In fact, if you use the constructor that takes a range, you don't even need the cast:
std::string string_from_uchar(const unsigned char * c, unsigned long long lc)
{
return std::string(c, c + lc);
}
It barely even warrants being in its own function.
Upvotes: 5