4

I come from C background, while learning C++ I came across the <string> header file. In C strings would be an array of characters terminated by '\0'.

However, in std::string I found that this is not the case, and on inserting/replacing a null character at any valid index does not trim the string as I would have expected.

string s; getline(cin, s); // remove all punctuation for(string::size_type i = 0, n = s.size(); i < n; i++) { if(ispunct(s[i])) s[i] = '\0'; } 

input: Hello, World!!!!

output: Hello World

expected output: Hello

On observing the above behaviour I assumed that strings in C++ are not null terminated. Then I found this question on SO Use of null character in strings (C++) This got me confused.

string s = "Hello\0, World"; cout << s << endl; 

output: Hello

expected output: Hello, World

It would be helpful if anyone could explain the reason behind this behaviour.

2
  • Think of std::string like a std::vector<char> that has a hidden extra element which is '\0'. That is an implementation detail though. The only guaranteed way to get a null-terminated array is through std::string::c_str(). Commented Mar 7, 2017 at 16:47
  • There is more than one kind of string in C++. There is the kind that is fully compatible with C, including null termination. There is another kind which is std::string from the <string> header. Strings of this second kind are not null terminated arrays of characters. Commented Mar 7, 2017 at 16:52

1 Answer 1

10

std::string supports embedded NUL characters*. The fact that your example code doesn't produce the expected result is, because you are constructing a std::string from a pointer to a zero-terminated string. There is no length information, and the c'tor stops at the first NUL character. s contains Hello, hence the output.

If you want to construct a std::string with an embedded NUL character, you have to use a c'tor that takes an explicit length argument:

std::string s("Hello\0, World", 13); std::cout << s << std::endl; 

produces this output:

Hello, World 


* std::string maintains an explicit length member, so it doesn't need to reserve a character to act as the end-of-string sentinel.

Sign up to request clarification or add additional context in comments.

3 Comments

you have to use a c'tor that takes an explicit length argument... or add the NUL character as an individual element.
@zett42: "If you want to construct a std::string with an embedded NUL character". You are constructing a string and then modify it. That's a different predicate. Using a c'tor taking an explicit length argument, an iterator pair, or an initializer list are the only ways to construct a std::string with embedded NUL characters.
Correct. I just gave another example how to stuff a NUL character into an std::string.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.