digitalmars.D.learn - char[] to string
- Jonathan Sternberg (17/17) Jun 10 2011 Why doesn't this work?
- Jonathan M Davis (9/33) Jun 10 2011 string is an alias for immutable(char)[]. The elements of a string can n...
- bearophile (4/8) Jun 11 2011 I didn't know this. Isn't it very good to give this bit of intelligence ...
- Jonathan M Davis (14/22) Jun 11 2011 Except that if you actually need it to create a copy for some reason, th...
- bearophile (4/8) Jun 11 2011 Thank you for the answer. I think this comment needs to go in the online...
- Timon Gehr (27/46) Jun 11 2011 Hi,
Why doesn't this work? import std.stdio; string copy_string(char [] input) { return input.dup; } int main() { char [] buf = ['h', 'e', 'l', 'l', 'o']; writeln( copy_string(buf) ); } I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it? I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language.
Jun 10 2011
On 2011-06-10 19:56, Jonathan Sternberg wrote:Why doesn't this work? import std.stdio; string copy_string(char [] input) { return input.dup; } int main() { char [] buf = ['h', 'e', 'l', 'l', 'o']; writeln( copy_string(buf) ); } I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it? I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language.string is an alias for immutable(char)[]. The elements of a string can never be altered. dup returns a mutable copy of a string (not const, not immutable). idup returns an immutable copy. So, in this case you want idup, not dup. Even better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would. - Jonathan M Davis
Jun 10 2011
Jonathan M Davis:Even better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would.I didn't know this. Isn't it very good to give this bit of intelligence to idup too? Bye, bearophile
Jun 11 2011
On 2011-06-11 05:12, bearophile wrote:Jonathan M Davis:Except that if you actually need it to create a copy for some reason, then it's a lot harder. However, to!() goes far beyond just improving idup anyway, because to!() should always be avoiding doing conversions if they're not actually necessary. So, if you trying to convert to char[] or const(wchar)[] or whatever, if no conversion is actually necessary, then the original argument will be returned. It doesn't matter what the original argument was. dup and idup only cover the case where you're trying to explicitly copy an array, whereas to!() covers any time that you're trying to convert to one to another type. So, it's generally best to use dup and idup only when you definitely want to make a copy. By using them, you're explicitly stating that you _want_ a copy to be made. If you just want a conversion, then to!() will do the trick in what is hopefully the most efficient way possible. - Jonathan M DavisEven better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would.I didn't know this. Isn't it very good to give this bit of intelligence to idup too?
Jun 11 2011
Jonathan M Davis:it's generally best to use dup and idup only when you definitely want to make a copy. By using them, you're explicitly stating that you _want_ a copy to be made. If you just want a conversion, then to!() will do the trick in what is hopefully the most efficient way possible.Thank you for the answer. I think this comment needs to go in the online docs (if it's not already present). Bye, bearophile
Jun 11 2011
On 2011-06-10 19:56, Jonathan Sternberg wrote:Why doesn't this work? import std.stdio; string copy_string(char [] input) { return input.dup; } int main() { char [] buf = ['h', 'e', 'l', 'l', 'o']; writeln( copy_string(buf) ); } I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it? I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language.Hi, You can append to a string. You only need char[] if you have to modify individual characters. // idup fixes your specific problem string copy_string(char [] input) { return input.idup; } string build_string(string str1, string str2){ string result; result~=str1; foreach(i;0..3) result~=str2; return result; } unittest{ assert(build_string("hi","lo") == "hilololo"); } If you really need char[] and you know that there is only one mutable reference to your data, then you can use std.exception.assumeUnique. (No idea why it is *there* though) import std.exception; string toUpper(char[] str){ char[] result = str.dup; foreach(ref x;result) if('a'<=x && x<='z') x+='A'-'a'; return result.assumeUnique(); // this is only safe if there really is only one reference to your data } Timon
Jun 11 2011