I have a function which needs to encode strings, which needs to be able to accept 0x00 as a valid 'byte'. My program needs to check the length of the string, however if I pass in "\x00"
to std::string
the length()
method returns 0.
How can I get the actual length even if the string is a single null character?
You're passing in an empty string. Use std::string(1, '\0')
instead.
Or std::string{ '\0' }
(thanks, @zett42)
std::string
is perfectly capable of storing nulls. However, you have to be wary, as const char*
is not, and you very briefly construct a const char*
, from which you create the std::string
.
std::string a("\x00");
This creates a constant C string containing only the null character, followed by a null terminator. But C strings don't know how long they are; so the string thinks it runs until the first null terminator, which is the first character. Hence, a zero-length string is created.
std::string b("");
b.push_back('\0');
std::string
is null-clean. Characters (\0
) can be the zero byte freely as well. So, here, there is nothing stopping us from correctly reading the data structure. The length of b
will be 1
.
In general, you need to avoid constructing C strings containing null characters. If you read the input from a file directly into std::string
or make sure to push the characters one at a time, you can get the result you want. If you really need a constant string with null characters, consider using some other sentinel character instead of \0
and then (if you really need it) replace those characters with '\0'
after loading into std::string
.
With C++14, you can use a string literal operator to store strings with null bytes:
using namespace std::string_literals;
std::string a = "\0"s;
std::string aa = "\0\0"s; // two null bytes are supported too