Yes and no. std::string can contain \0 characters internally without any problems or truncation, but C-style strings can't, so conversions between C-style and std::string often truncate if there are \0 characters internally. E.g.:
Code:
#include <iostream>
#include <string>
int main(){
std::string s1("Test_Test");
s1[4] = '\0';
std::string s2("Test\0Test");
std::string s3("Test\0Test",9);
std::cout << "S1.Length : " << s1.length() << std::endl;
std::cout << "S1 : " << s1 << std::endl;
std::cout << "S1.CString: " << s1.c_str() << std::endl;
std::cout << "S2.Length : " << s2.length() << std::endl;
std::cout << "S2 : " << s2 << std::endl;
std::cout << "S2.CString: " << s2.c_str() << std::endl;
std::cout << "S3.Length : " << s3.length() << std::endl;
std::cout << "S3 : " << s3 << std::endl;
std::cout << "S3.CString: " << s3.c_str() << std::endl;
}
produces:
Code:
S1.Length : 9
S1 : Test Test
S1.CString: Test
S2.Length : 4
S2 : Test
S2.CString: Test
S3.Length : 9
S3 : Test Test
S3.CString: Test
You note S1 and S3 are 9 characters long (and do NOT end at the \0 in the middle), but S2 is only 4 characters long, because this string literal:
std::string s2("Test\0Test");
is only *4* characters long. If you think about how that constructor works, the compiler puts a string literal "Test\0Test\0" somewhere in a data segment. Then the constructor is called with a pointer to the first character. It isn't passed the length, so it can do only one thing -- read until the first \0. For S3, the length is given, so the \0 is put in the middle.
Note also that, as you would expect, c_str() truncates the longer strings. A c-string ends with the first \0, so it's no surprise it works as it does.