3

I initialized a C++ string with a string literal and replaced a char with NULL.

When printed with cout << the full string is printed and the NULL char prints as blank.

When printed as c_str the string print stop at the NULL char as expected.

I'm a little confused. Does the action came from cout? or string?

int main(){
  std::string a("ab0cd");
  a[2] = '\0'; // '\0' is null char

  std::cout << a << std::endl; // abcd
  std::cout << a.c_str() << std::endl; // ab
}

Test it online.

I'm not sure whether the environment is related, anyway, I work with VSCode in Windows 10

Orace
  • 7,822
  • 30
  • 45
glaxy
  • 53
  • 4
  • Replace `c` with empty character: `''`. You are assigning a null character instead – Asesh Dec 30 '19 at 09:17
  • 3
    @Asesh There is no "empty character" in C++. Character is a number, there is no concept of "empty number". Empty string there is, of course. – hyde Dec 30 '19 at 09:28
  • Note that `NULL` is not a character, it's an obsolete (legacy C) macro for `nullptr`. Don't use it for chars. Use `'\0'` or just plain `0` instead. You are confusing `NULL` with ASCII character name NUL for this 0 char (which isn't defined as a standard symbol in C++), maybe. – hyde Dec 30 '19 at 10:00

3 Answers3

3

First you can narrow down your program to the following:

#include <iostream>
#include <string>

int main(){
    std::string a("ab0cd");
    a[2] = '\0'; // replace '0' with '\0' (same result as NULL, just cleaner)

    std::cout << a << "->" << a.c_str();
}

This prints

abcd->ab

That's because the length of a std::string is known. So it will print all of it's characters and not stop when encountering the null-character. The null-character '\0' (which is equivalent to the value of NULL [both have a value of 0, with different types]), is not printable, so you see only 4 characters. (But this depends on the terminal you use, some might print a placeholder instead)

A const char* represents (usually) a null-terminated string. So when printing a const char* it's length is not known and characters are printed until a null-character is encountered.

Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • `'\0' (which is equivalent to NULL and 0` - is equivalent to the value. The `'\0'` has the type `char`, `NULL` has the type `void*` and `0` has the type `int`. – KamilCuk Dec 30 '19 at 11:56
2

Contrary to what you seem to think, C++ string are not null terminated.

The difference in behavior came from the << operator overloads.

This code:

cout << a.c_str(); // a.c_str() is char*

As explained here, use the << overloads that came with cout, it print a char array C style and stop at the first null char. (the char array should be null terminated).

This code:

cout << a; // a is string

As explained here, use the << overloads that came with string, it print a string object that internally known is length and accept null char.

Orace
  • 7,822
  • 30
  • 45
0

string end limit (boundary) is not 0 (NULL) like simple char* but its size keep internally in its member data as it's actually user-defined type (an instantiated object) as opposed to primitive type, so

int main(){
  string a("abc0d");
  a[3] = 0; // '\0' is null char
    a.resize(2);
  std::cout << a << std::endl; // ab
  std::cout << a.c_str() << std::endl; // ab
}

i'm sorry change your code to be more comfortable, watch as it results in

ab
ab

good learning: http://www.cplusplus.com/reference/string/string/find/index.html