53

For regular C strings, a null character '\0' signifies the end of data.

What about std::string, can I have a string with embedded null characters?

1

4 Answers 4

57

Yes you can have embedded nulls in your std::string.

Example:

std::string s; s.push_back('\0'); s.push_back('a'); assert(s.length() == 2); 

Note: std::string's c_str() member will always append a null character to the returned char buffer; However, std::string's data() member may or may not append a null character to the returned char buffer.

Be careful of operator+=

One thing to look out for is to not use operator+= with a char* on the RHS. It will only add up until the null character.

For example:

std::string s = "hello"; s += "\0world"; assert(s.length() == 5); 

The correct way:

std::string s = "hello"; s += std::string("\0world", 6); assert(s.length() == 11); 

Storing binary data more common to use std::vector

Generally it's more common to use std::vector to store arbitrary binary data.

std::vector<char> buf; buf.resize(1024); char *p = &buf.front(); 

It is probably more common since std::string's data() and c_str() members return const pointers so the memory is not modifiable. with &buf.front() you are free to modify the contents of the buffer directly.

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

4 Comments

In C++9x &s.front() is also modifiable and guaranteed to point at a contiguous buffer. While there was no such guarantee in C++03, there are no known C++ implementations for which it didn't hold true in practice (which is partly why it was added to C++0x so quickly).
Note that as of C++11, .c_str() and .data are synonyms. In particular, this means that the string returned by .data must have a null terminator appended.
@PavelMinaev: I presume "C++9x" was a typo for "C++0x" (which became C++11 some time after you posted your comment).
s.append("\0world", 6); is better than s += std::string("\0world", 6);
9

Yes. A std::string is just a vector<char> with benefits.

However, be careful about passing such a beast to something that calls .c_str() and stops at the 0.

2 Comments

The first is not true, as I recently learned. Vector's swap preserves iterators and references to contents, string's not necessarily. stackoverflow.com/questions/25201758/…
@Notinlist: It has a different name, too! Oh the horror
2

You can, but why would you want to? Embedding NUL in an std::string is just asking for trouble, because functions to which you pass an std::string may very well use it's c_str() member, and most will assume that the first NUL indicates the end of the string. Hence this is not a good idea to do. Also note that in UTF-8, only '\0' will result in a 0, so even for i18n purposes, there is no justification for embedding NULs.

1 Comment

No, it's silly. "Don't use the full range of std::string's functionality, because you might pass the result of c_str() to C-string functions without also passing a length", really? Well, if you never do that, you'll be fine...
-1

Yep this is valid.

You can have a null character in the middle of the string.

However, if you use a std::string with a null character in the middle with a c string function your in undefined behaviour town - and nobody wants to be there!!!:

 int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!! 

1 Comment

strlen will just return the number of characters before the first null. It might be unanticipated behavior, but it's not undefined.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.