Converting a string to uint8_t array in C++
Asked Answered
A

3

16

I want an std::string object (such as a name) to a uint8_t array in C++. The function reinterpret_cast<const uint8_t*> rejects my string. And since I'm coding using NS-3, some warnings are being interpreted as errors.

Agglutination answered 5/10, 2011 at 16:24 Comment(1)
Show your code. What do you mean by "string object"? std::string or a pointer to a char.Chaumont
F
35

If you want a pointer to the string's data:

reinterpret_cast<const uint8_t*>(&myString[0])

If you want a copy of the string's data:

std::vector<uint8_t> myVector(myString.begin(), myString.end());
uint8_t *p = &myVector[0];
F answered 5/10, 2011 at 16:26 Comment(13)
That could in theory not be null terminatedTheorize
reinterpret_cast<const uint8_t*>(myString.c_str()) would work though (assuming myString is a std::string).Ipoh
@awoodland -- correct, but nul termination was not a requirement of the question. And, given that he wants uint8_t, not char, it is safe to assume he doesn't want a C-style string.Sentry
+1: The std::vector is great stuff. Creates a simple copy without memcpy or other C style stuff that likes to pop up in answers to these kinds of questions.Soelch
@Rob: use .c_str() instead of &myString[0] since std::string is not required to be contiguous.Magdeburg
@awoodland: While in C++03 it might not be null terminated, in C++11 the standard requires null termination of the buffer.Ay
@rubenvb: Interstingly, chances are that the code above ends up using memmove (maybe even memcpy) under the hood.Ay
@DavidRodríguez-dribeas - Good point, I'd forgotten that change in amongst all the really obvious ones!Theorize
@MooingDuck - Yes, std::string is not required to be contiguous, but std::string::operator[] is. From Herb Sutter: "[C++2003] does require &str[0] to cough up a pointer to contiguous string data (but not necessarily null-terminated!)" See lib.string.ops and lib.string.access.Sentry
@Rob: I was told C++03 did not require it. However, I see it in C++11 at least. §21.4.1 / 5 ...for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().Magdeburg
MooingDuck, Rob: C++11 std::string has contiguous storage, and if you glue the different parts together (ie the .c_str() function has to be O(1), so no copying the buffer), &s[0] and the std::string::data()´ function gives you a null-terminated character array nonetheless. On the other hand, all popular current (pre-c++11) implementations do have contiguous std::string` storage...Soelch
David: I know it does that under the hood, it just hides the fragile and unnecessary details away so the code is a lot more readable and bugs for such operations become non-existant.Soelch
Is there any guarantee that uint8_t has the same representation as char? If not, why is this valid?Penguin
U
14

String objects have a .c_str() member function that returns a const char*. This pointer can be cast to a const uint8_t*:

std::string name("sth");

const uint8_t* p = reinterpret_cast<const uint8_t*>(name.c_str());

Note that this pointer will only be valid as long as the original string object isn't modified or destroyed.

Unicameral answered 5/10, 2011 at 16:30 Comment(1)
Is there a way to do it backwards? For example, I would like to cast the uint8_t array to a c_str. Is that possible?Agglutination
S
2

If you need an actual array (not a pointer, as other answers have suggested; the difference is explained very nicely in this answer), you need to use std::copy from <algorithm>:

std::string str = "foo";
uint8_t arr[32];
std::copy(str.begin(), str.end(), std::begin(arr));
Schutt answered 10/1, 2021 at 19:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.