Why does the C++ standard allow the following?
#include <iostream>
#include <string>
int main()
{
std::string s(10, '\0'); // s.length() now is 10
std::cout << "string is " << s << ", length is " << s.length() << std::endl;
s.append(5, '\0'); // s.length() now is 15
std::cout << "string is " << s << ", length is " << s.length() << std::endl;
// the same with += char and push_back
// but:
s += "hello"; // s.length() returns 20 string is "hello"
std::cout << "string is " << s << ", length is " << s.length() << std::endl;
return 0;
}
Why does it add 0 and count it? It looks like broken integrity of string, doesn't it? But I checked standard and it is correct behavior.
Why does standard allows following?
Because the people designing C++ strings decided that such things should be allowed. I'm not sure if anyone that was part of the team that designed C++ strings are on SO... But since you yourself say that the standard allows it, that's the way it is, and I doubt it's about to change.
It's sometimes quite practical to have a string that can contain "anything". I can think of a few instances when I've had to work around the fact that C style strings can't contain zero-bytes. Along with the fact that long C style strings take a long time to find the length of, the main benefit of C++ strings is that they are not restricted to "what you can put in them" - that's a good thing in my book.
Not sure what is problem here.
Adding '\0'
in the middle of the std::string
changes nothing - null character is treated like any other. The only thing that can change is if you use .c_str()
with function that accepts null-terminated strings. But then it's not problem of .c_str()
, only with the function that treats '\0'
specially.
If you want to know how many characters has this string as if treated like null-terminated string, use
size_t len = strlen(s.c_str());
Note that it's O(n) operation, because that's how strlen
works.
If you ask why +=
operator doesn't add the implicit null character of string literal "hello"
to the string, I say the reverse (adding it) is unclear and definitely not what you want 99% of the time. On the other hand, if you want to add '\0'
to your string, just append it like a buffer:
char buffer[] = "Hello";
s.append(buffer, sizeof(buffer));
or (even better) drop the char arrays and null-terminated strings altogether and use C++-style replacements like std::string
as NTS-replacement, std::vector<char>
as contiguous buffer, std::vector
as dynamic array with pointers replacement, and std::array
(C++11) as standard C array replacement.
Also, (as mentioned by @AdamRosenfield in comments), your string after adding "hello"
does have in fact 20 characters, it's probably only that your terminal doesn't print nulls.
NUL
char '\0'
is the ending character for c style string
, not std::string
s. However, it supports this character to get values from a const char pointer so that it can find the end of a c-style string. Otherwise, it is treated just like other characters
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