How do you construct a std::string with an embedded null?

Viewed 50837

If I want to construct a std::string with a line like:

std::string my_string("a\0b");

Where i want to have three characters in the resulting string (a, null, b), I only get one. What is the proper syntax?

11 Answers

Since C++14

we have been able to create literal std::string

#include <iostream>
#include <string>

int main()
{
    using namespace std::string_literals;

    std::string s = "pl-\0-op"s;    // <- Notice the "s" at the end
                                    // This is a std::string literal not
                                    // a C-String literal.
    std::cout << s << "\n";
}

Before C++14

The problem is the std::string constructor that takes a const char* assumes the input is a C-string. C-strings are \0 terminated and thus parsing stops when it reaches the \0 character.

To compensate for this, you need to use the constructor that builds the string from a char array (not a C-String). This takes two parameters - a pointer to the array and a length:

std::string   x("pq\0rs");   // Two characters because input assumed to be C-String
std::string   x("pq\0rs",5); // 5 Characters as the input is now a char array with 5 characters.

Note: C++ std::string is NOT \0-terminated (as suggested in other posts). However, you can extract a pointer to an internal buffer that contains a C-String with the method c_str().

Also check out Doug T's answer below about using a vector<char>.

Also check out RiaD for a C++14 solution.

If you are doing manipulation like you would with a c-style string (array of chars) consider using

std::vector<char>

You have more freedom to treat it like an array in the same manner you would treat a c-string. You can use copy() to copy into a string:

std::vector<char> vec(100)
strncpy(&vec[0], "blah blah blah", 100);
std::string vecAsStr( vec.begin(), vec.end());

and you can use it in many of the same places you can use c-strings

printf("%s" &vec[0])
vec[10] = '\0';
vec[11] = 'b';

Naturally, however, you suffer from the same problems as c-strings. You may forget your null terminal or write past the allocated space.

I have no idea why you'd want to do such a thing, but try this:

std::string my_string("a\0b", 3);

The following will work...

std::string s;
s.push_back('a');
s.push_back('\0');
s.push_back('b');

Better to use std::vector<char> if this question isn't just for educational purposes.

I know it is a long time this question has been asked. But for anyone who is having a similar problem might be interested in the following code.

CComBSTR(20,"mystring1\0mystring2\0")

Almost all implementations of std::strings are null-terminated, so you probably shouldn't do this. Note that "a\0b" is actually four characters long because of the automatic null terminator (a, null, b, null). If you really want to do this and break std::string's contract, you can do:

std::string s("aab");
s.at(1) = '\0';

but if you do, all your friends will laugh at you, you will never find true happiness.

Related