Const Unsigned Char * to Std::String

string size after converting const unsigned char[] to std::string

case 1: input is not explicitly null-terminated, and likely those global arrays are placed in memory sequentially, so you get at least 48 bytes without zeros, finally it finds some zero 8 bytes ahead, so total is 56.

case 2: here you give it explicit length, and that's the correct way to do things in case of null terminator absence.

case 3: similar to case 1, but just starts from array 3, and takes same extra 8 bytes until null terminator found somewhere.

Solutions: either add null terminators (zero byte) or use variant with explicit length specification.

Way to get unsigned char into a std::string without reinterpret_cast?

Use the iterator constructor:

std::string my_std_string(my_txt, my_txt + my_txt_len);

This is assuming that you want the unsigned chars to be converted to char. If you want them to be reinterpreted, then you should use reinterpret_cast. That would be perfectly clean, since what you say is exactly what is done.

In your example, though, it doesn't make any difference, because all of the values in your array are within the range 0 to CHAR_MAX. So it's guaranteed that those values are represented the same way in char as they are in unsigned char, and hence that reinterpreting them is the same as converting them. If you had values greater then CHAR_MAX then implementations are allowed to treat them differently.

C++ conversion from unsigned char to std::string

To append a character you have to use the following overloaded method append

basic_string& append(size_type n, charT c);

For example

stroutput.append(1, characters[0]);
stroutput.append(1, characters[1]);

Otherwise use method push_back or the operator +=. For example

stroutput += characters[0];
stroutput += characters[1];

If you want to append the whole array or its part then you can write

stroutput.append( reinterpret_cast<char *>( characters ), sizeof( characters ) );

stroutput.append( reinterpret_cast<char *>( characters ), n );

where n is the number of characters of the array to append.

const unsigned char * to std::string

You could try:

temp_doc.uuid = std::string(reinterpret_cast<const char*>(
sqlite3_column_text(this->stmts.read_documents, 0)
));

While std::string could have a constructor that takes const unsigned char*, apparently it does not.

Why not, then? You could have a look at this somewhat related question: Why do C++ streams use char instead of unsigned char?

std::cout not properly printing std::string created by reinterpret_cast of unsigned char array

Change

std::cout << my_std_string << std::endl;    // Bad stuff happens :S

to

for( std::size_t i = 0; i < my_txt_len ; i++ )
{
std::cout << std::hex << static_cast<unsigned>(my_std_string[i]) << " " ;
}
std::cout << std::endl;

A std::string is a representation of a string, not purely an array of bytes. Therefore, passing it to std::cout will show a string. Your printf is printing individual values of your unsigned char array. The stl equivalent of this is an std::vector<unsigned char>.

You need to add the static_cast<unsigned>(). Otherwise std::cout will print each unsigned char value as a char ascii character. The output will be R _ s h ~ ) 3 t t s r U. You have to prevent this conversion by implicitly telling it.

error: cannot convert 'const unsigned char (*)[7]' to 'const unsigned char (*)[]' in initialization

TL;DR:

Replace

Sequence s1 = {&ic_1tc_1};

with

const uint8_t *s1[] = {ic_1tc_1};

Explanation:

Let's start with simple things.

When you omit the array size in a definition, the size is deduced:

int x[] = {1,2,3};

Here, the type of x is int[3].

Note that the type is not int[]. Types representing arrays of unknown bound are incomplete types, and no objects of such types can be created.

Above works even with typedefs:

typedef int array[];
array x = {1,2,3};

Note that the type of x is not array, since it's int[3] rather than int[].


Even though objects of incomplete types can't be created, you can create pointers to such types.

For example:

int (*ptr)[];

This declaration has the same effect as:

typedef int array[];
array *ptr;

The only thing this pointer could point to is int[], but since objects of such type can't be created, pointers to arrays of unknown bound aren't used often.

(Although I can imagine some peculiar use cases. You could declare an array to have an unknown bound and specify a size when defining it elsewhere. You could then form a pointer to the array using the declaration, and the type of such pointer will be T(*)[].)

You can't assign an address of int[N] to such a pointer, since formally int[] and int[N] are different types.

typedef int array[];
array x = {1,2,3};
array *ptr = &x; // Error, can't convert `int(*)[3]` to `int(*)[]`.

This is exactly what you're trying to do in your code.

One possible solution is to use the correct type for the pointer:

typedef int array[];
array x = {1,2,3};
int (*ptr)[3] = &x;

But since you said you need to have an array of pointers to arrays of various sizes, that is not an option.

Another possible solution is to cast the pointer, but that doesn't look convenient (and I'm not 100% sure using the resulting pointer is well-defined).

You probably should just store pointers to first elements of your arrays:

typedef int array[];
array x = {1,2,3};
int *ptr = x;

In your code it would look like so:

const Testcase ic_1tc_1 = {0x00, 0x10, 0x01, 0x61, 0x00, 0x30, 0x07};
const uint8_t *s1[] = {ic_1tc_1};

How to convert string to const unsigned char* without using reinterpret_cast (modern approach)

What is the correct way to change a string or const char* to const unsigned char*?

The correct way is to use reinterpret_cast.

If you want to avoid reinterpret_cast, then you must avoid the pointer conversion entirely, which is only possible by solving the XY-problem. Some options:

  • You could use std::basic_string<unsigned char> in the first place.
  • If you only need an iterator to unsigned char and not necessarily a pointer, then you could use std::ranges::views::transform which uses static cast for each element.
  • You could change the function that expects unsigned char* to accept char* instead.

If you cannot change the type of input and do need a unsigned char* and you still must avoid reinterpret cast, then you could create the std::basic_string<unsigned char> from the input using the transform view. But this has potential overhead, so consider whether avoiding reinterpret_cast is worth it.

Best way to join and store a char string with a wchar_t string in c++

std::vector<unsigned char> Buffer;

for (size_t i = 0; i < sizeof(section1); ++i)
Buffer.push_back((unsigned char) section1[i]);

for (size_t i = 0; i < section2.size(); ++i) {
unsigned short u = (unsigned short) section2[i];
Buffer.push_back((unsigned char) (u >> 8));
Buffer.push_back((unsigned char) (u & 0xFF));
}

for (size_t i = 0; i < sizeof(section3); ++i)
Buffer.push_back((unsigned char) section31[i]);

You can also use memcpy for section 1 and 3, and if you make assumptions about endianness for section2 as well. The above loops should be easy to read and understand though.

When done, you simply write Buffer.size() bytes starting from &Buffer[0]



Related Topics



Leave a reply



Submit