[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

changing a string

sarajan82

10/12/2008 9:22:00 PM

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
9 Answers

Ian Collins

10/12/2008 9:40:00 PM

0

sarajan82@gmail.com wrote:
> 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.

--
Ian Collins

Kai-Uwe Bux

10/12/2008 9:42:00 PM

0

sarajan82@gmail.com wrote:

> 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

sarajan82

10/12/2008 11:17:00 PM

0

On Oct 12, 2:41 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> saraja...@gmail.com wrote:
> > 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

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?

Kai-Uwe Bux

10/12/2008 11:24:00 PM

0

sarajan82@gmail.com wrote:

> On Oct 12, 2:41 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> saraja...@gmail.com wrote:
>> > 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
>
> 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

Victor Bazarov

10/13/2008 12:28:00 AM

0

Kai-Uwe Bux wrote:
> sarajan82@gmail.com wrote:
> [..]
>> 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.

Nit-pick: now you could do

s[2] = 0

or

s[2] = '\0'

(You could of course put a backslash between the space and the zero, but
there has to be a line break immediately following the backslash <g>)

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Stephen Horne

10/13/2008 4:26:00 AM

0

On Sun, 12 Oct 2008 14:22:01 -0700 (PDT), sarajan82@gmail.com wrote:

>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.

Erik Wikström

10/13/2008 4:01:00 PM

0

On 2008-10-13 01:16, sarajan82@gmail.com wrote:
> On Oct 12, 2:41 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> saraja...@gmail.com wrote:
>> > 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
>
> 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.

--
Erik Wikström

Juha Nieminen

10/13/2008 4:35:00 PM

0

Stephen Horne wrote:
> 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.

Stephen Horne

10/14/2008 3:12:00 AM

0

On Mon, 13 Oct 2008 16:34:33 GMT, Juha Nieminen
<nospam@thanks.invalid> wrote:

>Stephen Horne wrote:
>> 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.