user3351750
user3351750

Reputation: 937

NUL char in strings in C++

In the below code I am trying to replace the first character with '\0'.

I expected it to print an empty string, but in the output it just omits that and displays the rest of the characters.

int main()
{
    string str;
    cin >> str;

    str[0] = '\0';

    cout << str << "\n";
    return 0;
}

OUTPUT :

   testing
   esting

How do I terminate the string in C++?

PS: I was trying this approach of terminating the string in a different question in which I need to terminate in between.

Upvotes: 38

Views: 6639

Answers (7)

Dakorn
Dakorn

Reputation: 903

To get string that ends on first character you need to first extract char const* from string by calling method string::c_str(). Then it will be processed as you wish (like in C).

Upvotes: 4

QuestionC
QuestionC

Reputation: 10064

There are two approaches to strings.

In C, strings are zero-terminated, meaning the '\0' indicates the end of the string, which is what you are expected.

C++ (and most languages) uses counted strings, meaning the end of the string is indexed, so adding null terminators to the string won't terminate it. '\0' is a non-printing character, so when you print, you get the behavior you see. If you want to manipulate std::string length, you need to use the std::string methods (http://www.cplusplus.com/reference/string/string/).

C++ doesn't care about null terminators for strings. They are just used for C compatibility.

Incidentally, this should have the behavior you were expecting.

cout<<str.c_str()<<"\n";

See also

Why null-terminated strings? Or: null-terminated vs. characters + length storage

What's the rationale for null terminated strings?

Upvotes: 35

Jacob Minshall
Jacob Minshall

Reputation: 1054

Maybe use the good old printf like printf("%s", str.c_str()); this will print it out C style, and should terminate on the null character. things like strlen(str.c_str()); should work as well. What I suspect is that since C++ strings have a .size() function somewhere it probably has a int size; member, they don't waste any time checking for a null character every time they want to print. They can probably just say to print str.size() characters.

Upvotes: 3

Johann Gerell
Johann Gerell

Reputation: 25591

You just think you got

testing
esting

as output, but you actually got

testing
 esting
^
|
+-- "empty" \0 char

because the std::string still has the length of "testing", you just replaced the first character 't' with '\0'. When std::cout gets the string, it looks at the string length and outputs all its characters, which makes the '\0' cause an "empty" slot in the output.

To really clear the string, prefer to call std::string::clear(). Also valid is std::string::reset(0), but it's not as expressive (you can even assign an empty string... shudder). The implementation may or may not use a '\0' at all, so don't think of that as a way to fiddle with the externally observed representation.

Upvotes: 14

Sujith Gunawardhane
Sujith Gunawardhane

Reputation: 1311

According to the std::string implementation, the [] return the reference for the character in given position in the internal char array. When you set as str[8]= ‘\0’ it sets. You can check it by calling str.c_str() function. It return the internal array.

However, The cout reads it characters without null chars in the middle. It is the reason for the output.

const_reference operator[](size_type __n) const
{
    return *(_M_start + __n);
}

reference operator[](size_type __n)
{
    return *(_M_start + __n);
}

Upvotes: 4

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

A std::string resembles pretty much the functionality of a std::vector. If you want to erase all the elements of your std::string you could use std::string::clear

#include <iostream>
#include <string>

int main() {
  std::string str("testing");
  std::cout << str << std::endl;
  str.clear();
  std::cout << str << std::endl;
}

If you want to delete a particular character from your string (e.g., the 1st charater) you could use std::string::erase:

#include <iostream>
#include <string>

int main() {
  std::string str("testing");
  std::cout << str << std::endl;
  str.erase(str.begin());
  std::cout << str << std::endl;
}

If you want to remove particular characters from your string you could, as in the case of std::vector, use the erase-remove idiom:

#include <iostream>
#include <string>
#include <algorithm>

int main() {
  std::string str("testing");
  std::cout << str << std::endl;
  str.erase(std::remove_if(str.begin(), str.end(), [](char const &c){ return c == 't'; }), str.end());
  std::cout << str << std::endl;
}

Upvotes: 10

Marius Bancila
Marius Bancila

Reputation: 16338

std::string is not a null terminated string. If you want to empty it use the clear() method. If you want to remove an element of the string use the erase() method.

Upvotes: 52

Related Questions