Unexpected behavior when adding '\ 0' to std :: string

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 he add 0 and count? Seems like broken string integrity, right? But I checked the standard, and this is the correct behavior.

+4
source share
4 answers

Why does the standard allow the following?

Since people designing strings in C ++ decided that such things should be allowed. I'm not sure that someone who was part of the team that developed the C ++ lines is on SO ... But since you yourself say that the standard allows this, the way it is, and I doubt it will change .

Sometimes it’s pretty practical to have a string that can contain “anything.” I can come up with a few examples when I had to get around the fact that C style strings cannot contain null bytes. Along with the fact that long C-style strings take a long time to find length, the main advantage of C ++ strings is that they are not limited to “what you can put in them” - this is good in my book.

+6
source

Not sure if this is the problem.

Adding '\0' in the middle of std::string does not change anything - the null character is treated like any other. The only thing that can change is to use .c_str() with a function that accepts null-terminated strings. But then this is not a .c_str() problem, only with a function that processes '\0' specifically.

If you want to know how many characters this string has, as if it were being treated as a string with a null character, use

 size_t len = strlen(s.c_str()); 

Note that this is an O (n) operation, since strlen works.

If you ask why the += operator does not add the invisible null character of the string literal "hello" to the string, I say that the reverse (adding) is unclear and definitely not what you want 99% of the time, On the other hand, if you want to add '\0' in your line, just add it as a buffer:

 char buffer[] = "Hello"; s.append(buffer, sizeof(buffer)); 

or (even better) completely discard char arrays and null-terminated strings and use C ++ type replacements such as std::string , like NTS replacement, std::vector<char> as a continuous buffer, std::vector as dynamic array with replacement pointers and std::array (C ++ 11) as a standard replacement for array C.

Also (as @AdamRosenfield mentioned in the comments), your line after adding "hello" really has 20 characters, probably only that your terminal does not print zeros.

+4
source

NUL char '\0' is the ending character for c style string , not std::string s. However, it does support this character to get values ​​from a const char pointer so that it can find the end of the c-style string. Otherwise, it is treated in the same way as other characters.

+2
source

std :: string is more of a container for characters than anything else, and \ 0 is a character. For an example in the real world, check out CreateProcess on Windows. The lpEnvironment parameter takes a zero-terminated block with zero-termination (i.e., A=1\0B=2\0C=3\0\0 ). If you are building a block, it is convenient to use std :: string.

0
source

Source: https://habr.com/ru/post/1489075/


All Articles