I am trying to convert a boost UUID to a char *
without having to use std::string
at all.
I mostly modified the to_string
method from https://www.boost.org/doc/libs/1_68_0/boost/uuid/uuid_io.hpp to my own version. However, it fails on certain UUIDs.
Here is my modification:
#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/uuid_generators.hpp>
using UUID = boost::uuids::uuid;
static constexpr std::size_t UUID_STR_LEN = 37;
inline char uuid_byte_to_char(size_t i)
{
if (i <= 9) {
return static_cast<char>('0' + i);
} else {
return static_cast<char>('a' + (i - 10));
}
}
inline void uuid_to_cstr(UUID const& uuid, char out[UUID_STR_LEN])
{
std::size_t out_i = 0;
std::size_t dash_i = 0;
for (UUID::const_iterator it_data = uuid.begin(); it_data != uuid.end(); ++it_data, ++dash_i) {
const size_t hi = ((*it_data) >> 4) & 0x0F;
out[out_i++] = uuid_byte_to_char(hi);
const size_t lo = (*it_data) & 0x0F;
out[out_i++] = uuid_byte_to_char(lo);
if (dash_i == 3 || dash_i == 5 || dash_i == 7 || dash_i == 9) {
out[out_i++] += '-';
}
}
out[UUID_STR_LEN - 1] = '\0';
}
Usage:
int main() {
UUID uuid(uuid_generator());
char uuid_cstr(UUID_STR_LEN];
uuid_to_str(uuid uuid_cstr);
std::cout << uuid_cstr << "\n";
}
So if the UUID was cd0fa728-e7d6-4578-9450-7beb284e0103
for example this works fine.
However, for 0cf31c43-7621-407c-94d6-6d593bae96e8
what I actually end up getting is 0cf31c43-7621�407cQ94d6-6d593bae96e8
.
What's the problem in my code? As far as I'm aware, my char manipulations mimic what the std::string is doing minus the temporary copies due to the constant appending. Or am I mistaken?
Your buffer char uuid_cstr[UUID_STR_LEN];
was allocated onto stack so it has garbage values, all elements in buffer has some initial value probably not 0.
1) You can set all items to zero by
char uuid_cstr[UUID_STR_LEN];
memset (uuid_cstr,0,UUID_STR_LEN);
then the following statement can work
out[out_i++] += '-';
2) Or use the assignment
out[out_i++] = '-';