Maybe it's just the lack of coffee, but I'm trying to create a std::string
from a null-terminated char
array with a known maximum length and I don't know, how to do it.
auto s = std::string(buffer, sizeof(buffer));
.. was my favorite candidate but since C++ strings are not null-terminated this command will copy sizeof(buffer)
bytes regardless of any contained '\0'.
auto s = std::string(buffer);
.. copies from buffer
until \0
is found. This is almost what I want but I can't trust the receive buffer so I'd like to provide a maximum length.
Of course, I can now integrate strnlen()
like this:
auto s = std::string(buffer, strnlen(buffer, sizeof(buffer)));
But that seems dirty - it traverses the buffer twice and I have to deal with C-artifacts like string.h
and strnlen()
(and it's ugly).
How would I do this in modern C++?
Actually, as of C++11 std::string is guaranteed to be null terminated. Specifically, s[s. size()] will always be '\0' .
A C-style string is a null (denoted by \0 ) terminated char array. The null occurs after the last character of the string. For an initialization using double quotes, "...", the compiler will insert the null .
If you will use the array as a string, it must include the terminating null character. The terminating null character is part of the array and must be included in its size.
char arrays are not automatically NULL terminated, only string literals, e.g. char *myArr = "string literal"; , and some string char pointers returned from stdlib string methods.
Something like this could work in a single pass..
auto eos = false;
std::string s;
std::copy_if(buffer, buffer + sizeof(buffer), std::back_inserter(s),
[&eos](auto v) {
if (!eos) {
if (v) {
return true;
}
eos = true;
}
return false;
});
const char* end = std::find(buffer, buffer + sizeof(buffer), '\0');
std::string s(buffer, end);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With