www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Modify char in string

reply "Tim" <nrgyzer gmail.com> writes:
Hi everyone,

is there any chance to modify a char in a string like:

void main()
{
    string sMyText = "Replace the last char_";
    sMyText[$ - 1] = '.';
}

But when I execute the code above I'm always getting "cannot 
modify immutable expression at sMyText[__dollar -1LU]". I though 
D supported such modifications anytime. How can I do that now...?
May 18 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Tim:

 is there any chance to modify a char in a string like:

 void main()
 {
    string sMyText = "Replace the last char_";
    sMyText[$ - 1] = '.';
 }

 But when I execute the code above I'm always getting "cannot 
 modify immutable expression at sMyText[__dollar -1LU]". I 
 though D supported such modifications anytime. How can I do 
 that now...?
D strings are immutable. And mutating immutable variables is a bug in D. So you can't do that. You have to work around the problem. One solution is to not have a string, but something more like a char[] in the first place, and mutate it. If you have a string, you can do (this works with the current GIT DMD compiler): /// Not Unicode-safe. string dotLast(in string s) pure nothrow { auto ds = s.dup; ds[$ - 1] = '.'; return ds; } void main() { import std.stdio; immutable input = "Replace the last char_"; immutable result = input.dotLast; result.writeln; } That code doesn't work if your text contains more than the Ascii chars. Bye, bearophile
May 18 2014
prev sibling parent reply "Chris Cain" <zshazz gmail.com> writes:
On Sunday, 18 May 2014 at 18:55:59 UTC, Tim wrote:
 Hi everyone,

 is there any chance to modify a char in a string like:
As you've seen, you cannot modify immutables (string is an immutable(char)[]). If you actually do want the string to be modifiable, you should define it as char[] instead. Then your example will work: void main() { char[] sMyText = "Replace the last char_"; sMyText[$ - 1] = '.'; } If you actually want it to be immutable, you can still do it, but you can't modify in-place, you must create a new string that looks like what you want: void main() { string sMyText = "Replace the last char_"; sMyText = sMyText[0 .. $-1] ~ "."; // you would do //sMyText[0 .. 5] ~ "." ~ sMyText[6..$]; // to "replace" something in the 5th position } Note that the second method allocates and uses the GC more (which is perfectly fine, but not something you want to do in a tight loop). For most circumstances, the second method is good.
May 18 2014
parent reply "Tim" <nrgyzer gmail.com> writes:
On Sunday, 18 May 2014 at 19:09:52 UTC, Chris Cain wrote:
 On Sunday, 18 May 2014 at 18:55:59 UTC, Tim wrote:
 Hi everyone,

 is there any chance to modify a char in a string like:
As you've seen, you cannot modify immutables (string is an immutable(char)[]). If you actually do want the string to be modifiable, you should define it as char[] instead. Then your example will work: void main() { char[] sMyText = "Replace the last char_"; sMyText[$ - 1] = '.'; } If you actually want it to be immutable, you can still do it, but you can't modify in-place, you must create a new string that looks like what you want: void main() { string sMyText = "Replace the last char_"; sMyText = sMyText[0 .. $-1] ~ "."; // you would do //sMyText[0 .. 5] ~ "." ~ sMyText[6..$]; // to "replace" something in the 5th position } Note that the second method allocates and uses the GC more (which is perfectly fine, but not something you want to do in a tight loop). For most circumstances, the second method is good.
Thanks - I already tried: void main() { char[] sMyText = "Replace the last char_"; sMyText[$ - 1] = '.'; } but I always getting "Error: cannot implicitly convert expression ("Replace the last char_") of type string to char[]". I know, I can use cast(char[]) but I don't like casts for such simple things...
May 19 2014
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/19/2014 10:07 AM, Tim wrote:

 I already tried:

       void main()
       {
          char[] sMyText = "Replace the last char_";
          sMyText[$ - 1] = '.';
       }

 but I always getting "Error: cannot implicitly convert expression
 ("Replace the last char_") of type string to char[]".
That's a good thing because that string literal is immutable. If that code compiled you would get undefined behavior.
 I know, I can use cast(char[])
Unfortunately, not in this case. That undefined behavior would manifest itself as a "Segmentation fault" on many systems. :)
 but I don't like casts for such simple things...
What you want to do makes sense only if you have a mutable ASCII string. Such strings are generated at run time so the problem is usually a non issue: import std.stdio; void main() { foreach (line; stdin.byLine) { char[] s = line.dup; // (or .idup if you want immutable) s[$-1] = '.'; writefln("Input : %s", line); writefln("Output: %s", s); } } Ali
May 19 2014