129

Will the below string contain the null terminator '\0'?

std::string temp = "hello whats up";
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
mister
  • 3,303
  • 10
  • 31
  • 48
  • 5
    [Will std::string always be null-terminated in C++11?](http://stackoverflow.com/questions/6077189/will-stdstring-always-be-null-terminated-in-c11). – Jesse Good Aug 01 '12 at 05:01
  • 2
    At it stands now, the accepted answer from @jahhaj conflicts with the answer from user529758, whose answer is arguably more up to date. While perusing, I skipped Jesse Good's comment, so this is here to emphasize its importance. – Jonathan Komar Jun 19 '20 at 07:06

6 Answers6

132

No, but if you say temp.c_str() a null terminator will be included in the return from this method.

It's also worth saying that you can include a null character in a string just like any other character.

string s("hello");
cout << s.size() << ' ';
s[1] = '\0';
cout << s.size() << '\n';

prints

5 5

and not 5 1 as you might expect if null characters had a special meaning for strings.

Rico
  • 58,485
  • 12
  • 111
  • 141
jahhaj
  • 3,021
  • 1
  • 15
  • 8
  • 13
    If you call `temp.c_str()` the null character will be included. If you really need it in the string just add it like any other character. `temp.push_back('\0')`. Now `temp.c_str()` will include *two* null characters. – jahhaj Aug 01 '12 at 05:02
  • 2
    @dupdupdup, as some of the replies have mentioned, if you need a null-terminated string you should call a s.c_str() on the constructred object. It will return a pointer to character array that is guaranteed to have '\0' at the end. – Maksim Skurydzin Aug 01 '12 at 05:03
  • @Rico, Jahhaj How to terminate the string then. For eg - I added few characters to my string as str[i]. Now I'm not able to print it using cout. – Bhavuk Mathur Aug 23 '16 at 00:52
  • To add to your point : Since the operator << is overloaded so, cout < – AnotherDeveloper Feb 02 '18 at 04:10
  • 5
    Actually, as of C++11 `std::string` is guaranteed to be null terminated. Specifically, `s[s.size()]` will always be `'\0'`. – themeeman Nov 08 '21 at 10:23
  • for learners) After the above code, `cout< – starriet Jul 06 '23 at 02:46
114

Not in C++03, and it's not even guaranteed before C++11 that in a C++ std::string is continuous in memory. Only C strings (char arrays which are intended for storing strings) had the null terminator.

In C++11 and later, mystring.c_str() is equivalent to mystring.data() is equivalent to &mystring[0], and mystring[mystring.size()] is guaranteed to be '\0'.

In C++17 and later, mystring.data() also provides an overload that returns a non-const pointer to the string's contents, while mystring.c_str() only provides a const-qualified pointer.

A. MacGillivray
  • 449
  • 4
  • 11
  • 6
    With C++11, strings are now guaranteed to be contiguous in memory. – zneak Aug 01 '12 at 04:53
  • @zneak thanks! Updated. But I doubt there are any at least reasonably C++11-compilant compilers... even GCC has broken support for it. –  Aug 01 '12 at 04:54
  • 7
    @H2CO3 : C++11 aside, this was addressed in [DR 530](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530) in _2005_. The vast majority of standard library implementations have stored string data in contiguous memory for at least as long. – ildjarn Aug 01 '12 at 05:07
  • 5
    Thank you @ildjarn, I was looking for that exactly. Part of the rationale for the move was that no one on the committee knew of an STL implementation that did not use continuous memory. – zneak Aug 01 '12 at 05:09
  • http://stackoverflow.com/questions/11752857/what-is-the-meaning-of-continuous-memory-in-c – mister Aug 01 '12 at 05:11
  • 1
    With C++17, there is now a `char * std::string::data()` function (returns a modifiable / non-const pointer to the string's contents). See the C++ reference: https://en.cppreference.com/w/cpp/string/basic_string/data Related thread: https://stackoverflow.com/a/34179377/9909817 – A. MacGillivray Aug 05 '21 at 15:14
  • Can you dereference str::string::end() and be sure to get NULL in C++11? – Andrew May 30 '23 at 19:29
21

This depends on your definition of 'contain' here. In

std::string temp = "hello whats up";

there are few things to note:

  • temp.size() will return the number of characters from first h to last p (both inclusive)
  • But at the same time temp.c_str() or temp.data() will return with a null terminator
  • Or in other words int(temp[temp.size()]) will be zero

I know, I sound similar to some of the answers here but I want to point out that size of std::string in C++ is maintained separately and it is not like in C where you keep counting unless you find the first null terminator.

To add, the story would be a little different if your string literal contains embedded \0. In this case, the construction of std::string stops at first null character, as following:

std::string s1 = "ab\0\0cd";   // s1 contains "ab",       using string literal
std::string s2{"ab\0\0cd", 6}; // s2 contains "ab\0\0cd", using different ctr
std::string s3 = "ab\0\0cd"s;  // s3 contains "ab\0\0cd", using ""s operator

References:

aniliitb10
  • 1,259
  • 10
  • 14
  • What do you mean by "`int(temp[temp.size()])` will be zero"? Since `temp` is a std::string, `temp[temp.size()]` [can be undefined](https://en.cppreference.com/w/cpp/string/basic_string/operator_at). (We can't do `temp.at(temp.size())` - out of range). – starriet Sep 27 '22 at 01:27
  • @starriet `temp[temp.size()]` is defined since C++11. It's only assigning anything but a `char{}` to it that would make it undefined. Reading it is never undefined. `at` checks for `pos >= size()` but for `operator[]` the behavior is only undefined for `pos > size()`. – Ted Lyngmo Feb 08 '23 at 08:25
2

Yes if you call temp.c_str(), then it will return null-terminated c-string.

However, the actual data stored in the object temp may not be null-terminated, but it doesn't matter and shouldn't matter to the programmer, because when then programmer wants const char*, he would call c_str() on the object, which is guaranteed to return null-terminated string.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    Nor will the null terminator (if it exists) be included in the return from `temp.size()`. – jahhaj Aug 01 '12 at 04:54
1

With C++ strings you don't have to worry about that, and it's possibly dependent of the implementation.

Using temp.c_str() you get a C representation of the string, which will definitely contain the \0 char. Other than that, i don't really see how it would be useful on a C++ string

Naps62
  • 960
  • 6
  • 17
1

std::string internally keeps a count of the number of characters. Internally it works using this count. Like others have said, when you need the string for display or whatever reason, you can its c_str() method which will give you the string with the null terminator at the end.

Superman
  • 3,027
  • 1
  • 15
  • 10
  • 1
    Can you give some references for this statement," std::string internally keeps a count of the number of characters. Internally it works using this count" – rooni Nov 22 '17 at 13:29