string question

J

junw2000

In the following code:

std::string s1;
s1 = "ABCDE";
std::cout<<s1<<std::endl;
s1[3] = '\0'; //LINE1
std::cout<<s1<<std::endl; //LINE2

At LINE1, I add a NULL terminator at s1[3], so s1 should end at s1[3],
right?
Why LINE2 prints "ABCE" other than "ABC"?

Thanks.

Jack
 
O

Owen Jacobson

In the following code:

std::string s1;
s1 = "ABCDE";
std::cout<<s1<<std::endl;
s1[3] = '\0'; //LINE1
std::cout<<s1<<std::endl; //LINE2

At LINE1, I add a NULL terminator at s1[3], so s1 should end at s1[3],
right?

No. std::string is not null-terminated. The character '\0' is not
treated specially in any way. The std::string "\0\0\0\0\0"[0] contains
five characters.

-Owen

[0] Not a valid string literal, but you know what I mean, I hope.
 
J

junw2000

Owen said:
In the following code:

std::string s1;
s1 = "ABCDE";
std::cout<<s1<<std::endl;
s1[3] = '\0'; //LINE1
std::cout<<s1<<std::endl; //LINE2

At LINE1, I add a NULL terminator at s1[3], so s1 should end at s1[3],
right?

No. std::string is not null-terminated. The character '\0' is not
treated specially in any way. The std::string "\0\0\0\0\0"[0] contains
five characters.

-Owen

[0] Not a valid string literal, but you know what I mean, I hope.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I do not know :). What does it mean?
 
O

Owen Jacobson

Owen said:
No. std::string is not null-terminated. The character '\0' is not
treated specially in any way. The std::string "\0\0\0\0\0"[0] contains
five characters.

-Owen

[0] Not a valid string literal, but you know what I mean, I hope.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I do not know :). What does it mean?

Consider the following snippet:

std::string someString = "\0";

std::cout << someString.length () << std::endl;

will print 0, because "\0" expands to the char array {'\0', '\0'};.
std::string's constructor which takes a const char* treats the incoming
string as a C-style null-terminated string, and stops scanning at the
first '\0', even though that occurs before the end of the array.

I should probably have written "not a useful string literal", because it's
valid, but doesn't do what it looks like it might do (to me, anyways).

However, once you have an std::string, you can append or insert '\0' into
it, where it acts like a normal character:

someString += '\0';
std::cout << someString.length () << std::endl;

will print '1', because the '\0' character is considered part of the
string. (It's unprintable, so cout << someString << endl will likely
print nothing.)
 
N

novostik

Still confused...how does it relate to the main question-as the array
exist before and so it should print the first three characters only.
could you plz be specific
Owen said:
Owen said:
No. std::string is not null-terminated. The character '\0' is not
treated specially in any way. The std::string "\0\0\0\0\0"[0] contains
five characters.

-Owen

[0] Not a valid string literal, but you know what I mean, I hope.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I do not know :). What does it mean?

Consider the following snippet:

std::string someString = "\0";

std::cout << someString.length () << std::endl;

will print 0, because "\0" expands to the char array {'\0', '\0'};.
std::string's constructor which takes a const char* treats the incoming
string as a C-style null-terminated string, and stops scanning at the
first '\0', even though that occurs before the end of the array.

I should probably have written "not a useful string literal", because it's
valid, but doesn't do what it looks like it might do (to me, anyways).

However, once you have an std::string, you can append or insert '\0' into
it, where it acts like a normal character:

someString += '\0';
std::cout << someString.length () << std::endl;

will print '1', because the '\0' character is considered part of the
string. (It's unprintable, so cout << someString << endl will likely
print nothing.)
 
M

Markus Moll

Hi

Still confused...how does it relate to the main question-as the array
exist before and so it should print the first three characters only.
could you plz be specific

It's the first thing you quote:
Owen Jacobson wrote:

No. std::string is not null-terminated. The character '\0' is not
treated specially in any way. The std::string "\0\0\0\0\0"[0]
contains five characters.

Markus
 
R

rossum

In the following code:

std::string s1;
s1 = "ABCDE";
std::cout<<s1<<std::endl;
s1[3] = '\0'; //LINE1
std::cout<<s1<<std::endl; //LINE2

At LINE1, I add a NULL terminator at s1[3], so s1 should end at s1[3],
right?
Why LINE2 prints "ABCE" other than "ABC"?

Thanks.

Jack
std::string does not use a \0 terminator, instead it uses a separately
held length. Hence s1 starts as:

length = 5
chars = {A, B, C, D, E}

When you change s1[3] you are not changing the length, just one of the
characters:

length = 5
chars = {A, B, C, \0, E}

When you print s1 it prints five characters as specified by the
length. However the \0 does not print so you get "ABCE".

rossum
 
R

Rolf Magnus

Please don't top-post.

Still confused...how does it relate to the main question-as the array
exist before and so it should print the first three characters only.
could you plz be specific

There are two types of strings in C++, the C style strings, which are
nothing more than raw arrays of char that are terminated by a '\0'
character and std::string, which has no special termination character,
because it's a class that keeps track of its size.

Whenever you deal with a C style string, the '\0' character is seen as "end
of string" character, so every function that deals with them will stop
reading at that character.
Functions that work on std::string don't do that, because '\0' is not a
special character there. They stop when they are at the character with an
index equal to length()-1.
If you write "\0Hello world", that's a string literal. You can make an
std::string from it by using the constructor that takes a const char* as
argument. However, that constructor assumes that you give it a C style
string, i.e. terminated by a '\0' character (how else would it know the
length?). Therefore, the string object will be empty, because the first
character in the C style string was '\0'.
However, if you add a single char with
someString += '\0';
to your std::string, that char is just simply appended to the string. If you
insert a character somewhere in the middle of the string with '\0' (like
you did in the original example), the length of the string won't change,
because '\0' is not treated specially. When you send that string to cout,
there is no reason to stop at the '\0'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top