changing a string

S

sarajan82

Hi All,

I have a string represented by char* (I do not user string class):
char *s="abcd";

Assume I want to remove the last two elements of s. What is the
standard solution for this?
Can I just change the value of s[2] to '\0'?

Thanks a lot
Sara
 
I

Ian Collins

Hi All,

I have a string represented by char* (I do not user string class):
char *s="abcd";
"abcd" is a string literal, it is a constant so you can't change it.
You can try, but the result is undefined.

If you want to manipulate strings, use std::string.
 
K

Kai-Uwe Bux

Hi All,

I have a string represented by char* (I do not user string class):
char *s="abcd";

Assume I want to remove the last two elements of s. What is the
standard solution for this?

Using std::string.
Can I just change the value of s[2] to '\0'?

No.

The reason is a little involved. For starters, if you had

char const * s = "abcd"; // (*)

it would be obvious that you are trying to modify something declared const.
This is undefined behavior.

Second, you have

char * s = "abcd"

and that happens to be roughly equivalent to (*). The right hand side is
const and the conversion to something non-const is only allowed for
compatibility with C. The fact remains that you are trying to modify
the "abcd" string, which is const. That is still undefined behavior, see
[7.1.5.1/4] and [2.13.4/1] or just [2.13.4/2].


Best

Kai-Uwe Bux
 
S

sarajan82

I have a string represented by char* (I do not user string class):
char *s="abcd";
Assume I want to remove the last two elements of s. What is the
standard solution for this?

Using std::string.
Can I just change the value of s[2] to '\0'?

No.

The reason is a little involved. For starters, if you had

  char const * s = "abcd";      // (*)

it would be obvious that you are trying to modify something declared const.
This is undefined behavior.

Second, you have

  char * s = "abcd"

and that happens to be roughly equivalent to (*). The right hand side is
const and the conversion to something non-const is only allowed for
compatibility with C. The fact remains that you are trying to modify
the "abcd" string, which is const. That is still undefined behavior, see
[7.1.5.1/4] and [2.13.4/1] or just [2.13.4/2].

Best

Kai-Uwe Bux

What if I use:
char s[4];
s[0]='a';
s[1]='b';
s[2]='c';
s[3]='d';
instead?
Is there any built-in method to erase a part of string defined as
char[] instead of std::string?
 
K

Kai-Uwe Bux

I have a string represented by char* (I do not user string class):
char *s="abcd";
Assume I want to remove the last two elements of s. What is the
standard solution for this?

Using std::string.
Can I just change the value of s[2] to '\0'?

No.

The reason is a little involved. For starters, if you had

char const * s = "abcd";      // (*)

it would be obvious that you are trying to modify something declared
const. This is undefined behavior.

Second, you have

char * s = "abcd"

and that happens to be roughly equivalent to (*). The right hand side is
const and the conversion to something non-const is only allowed for
compatibility with C. The fact remains that you are trying to modify
the "abcd" string, which is const. That is still undefined behavior, see
[7.1.5.1/4] and [2.13.4/1] or just [2.13.4/2].

Best

Kai-Uwe Bux

What if I use:
char s[4];
s[0]='a';
s[1]='b';
s[2]='c';
s[3]='d';
instead?

Then you are not 0-terminated. Consequently, many function calls to standard
C-string functions will have undefined behavior.

Is there any built-in method to erase a part of string defined as
char[] instead of std::string?

Not that I would be aware of. But now you could do s[2] = \0. That, of
course, would not erase a block in the middle.


What is your reason not to use std::string?


Best

Kai-Uwe Bux
 
S

Stephen Horne

Hi All,

I have a string represented by char* (I do not user string class):
char *s="abcd";

Assume I want to remove the last two elements of s. What is the
standard solution for this?

This kind of string manipulation is more C than C++, but there is
still a library for working with these kinds of strings.

#include <cstring>

It's a bad idea to manipulate a string assigned from a literal,
though. That is...

char *s="abcd";
s[2] = 0; // Don't do this!

Instead, use...

char* s = new char [BUFFERSIZE];
std::strncpy (s, "abcd", BUFFERSIZE);
s [2] = 0;

In the above, I cut the string short by writing a new null terminator
to the appropriate character position.

However, this kind of stuff is very error prone, and tends to be a
cause of crashes, memory corruption, security issues and more. It's
very easy to end up reading/writing past the end of your buffers and
so on. Seriously, just use the std::string class - you'll regret it if
you don't.
 
E

Erik Wikström

I have a string represented by char* (I do not user string class):
char *s="abcd";
Assume I want to remove the last two elements of s. What is the
standard solution for this?

Using std::string.
Can I just change the value of s[2] to '\0'?

No.

The reason is a little involved. For starters, if you had

char const * s = "abcd"; // (*)

it would be obvious that you are trying to modify something declared const.
This is undefined behavior.

Second, you have

char * s = "abcd"

and that happens to be roughly equivalent to (*). The right hand side is
const and the conversion to something non-const is only allowed for
compatibility with C. The fact remains that you are trying to modify
the "abcd" string, which is const. That is still undefined behavior, see
[7.1.5.1/4] and [2.13.4/1] or just [2.13.4/2].

Best

Kai-Uwe Bux

What if I use:
char s[4];
s[0]='a';
s[1]='b';
s[2]='c';
s[3]='d';
instead?

If you must use char-arrays use

char s[] = "abcd";

this will ensure that the string is properly null-terminated.
Is there any built-in method to erase a part of string defined as
char[] instead of std::string?

Look up <cstring> in your favourite C++ reference.
 
J

Juha Nieminen

Stephen said:
Instead, use...

char* s = new char [BUFFERSIZE];
std::strncpy (s, "abcd", BUFFERSIZE);
s [2] = 0;

Given this is almost *exactly* replicating what std::string would do
(except that it would do it more safely), I really can't understand why
you are giving this as a viable solution. Why not give the solution
using std::string rather than this? The end result will be the same, but
much safer and more didactic.
 
S

Stephen Horne

Stephen said:
Instead, use...

char* s = new char [BUFFERSIZE];
std::strncpy (s, "abcd", BUFFERSIZE);
s [2] = 0;

Given this is almost *exactly* replicating what std::string would do
(except that it would do it more safely), I really can't understand why
you are giving this as a viable solution. Why not give the solution
using std::string rather than this? The end result will be the same, but
much safer and more didactic.

Read the rest of the post.

In short, I *didn't* give it as a viable solution, I made it pretty
clear that it *wasn't* a sensible solution. But that doesn't mean that
I take an "I know this but you are not worthy" attitude.

Take a "do what I say" attitude and people will ignore you and do what
they want anyway. So provide the facts and explain why it's a bad
idea. That way, when they ignore you and do it anyway, they don't get
to blame your attitude when it all goes horribly wrong.
 

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
474,169
Messages
2,570,919
Members
47,459
Latest member
Vida00R129

Latest Threads

Top