digitalmars.D.learn - string[] to char**
- simendsjo (1/1) Mar 23 2012 What's the best way to convert char** from string[]?
- bearophile (13/14) Mar 23 2012 This is one way to do it:
- Andrej Mitrovic (2/4) Mar 23 2012 This is asked so frequently that I think we could consider adding it to ...
- simendsjo (3/8) Mar 24 2012 Yes. The first thing I tried was to!(char**)(strings), but that didn't w...
- simendsjo (9/23) Mar 24 2012 Thanks. A lot shorter and safer than my current approach. I also expect ...
- simendsjo (3/34) Mar 24 2012 Oh, I didn't find toStringz, so I turned it into:
- bearophile (5/7) Mar 24 2012 That's wrong syntax, that 2.059head doesn't enforce yet, map needs an en...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (36/37) Mar 23 2012 In C, char** communicates transfer of ownership. Is that what you are
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (5/8) Mar 23 2012 Ok, I once again misunderstood the question. :( My question in the
- simendsjo (8/46) Mar 24 2012 ed =
What's the best way to convert char** from string[]?
Mar 23 2012
On Friday, 23 March 2012 at 15:48:12 UTC, simendsjo wrote:What's the best way to convert char** from string[]?This is one way to do it: import std.algorithm, std.array, std.string, core.stdc.stdio; void main() { auto data = ["red", "yellow", "green"]; immutable(char)** p = array(map!toStringz(data)).ptr; printf("%s %s %s\n", p[0], p[1], p[2]); } Note: the pointer array is managed by the D GC. With DMD 2.059: immutable(char)** p = data.map!toStringz().array().ptr; Bye, bearophile
Mar 23 2012
On 3/23/12, bearophile <bearophileHUGS lycos.com> wrote:This is one way to do it: immutable(char)** p = array(map!toStringz(data)).ptr;This is asked so frequently that I think we could consider adding it to Phobos.
Mar 23 2012
On Fri, 23 Mar 2012 22:42:08 +0100, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 3/23/12, bearophile <bearophileHUGS lycos.com> wrote:Yes. The first thing I tried was to!(char**)(strings), but that didn't workThis is one way to do it: immutable(char)** p = array(map!toStringz(data)).ptr;This is asked so frequently that I think we could consider adding it to Phobos.
Mar 24 2012
On Fri, 23 Mar 2012 17:09:18 +0100, bearophile <bearophileHUGS lycos.com> wrote:On Friday, 23 March 2012 at 15:48:12 UTC, simendsjo wrote:Thanks. A lot shorter and safer than my current approach. I also expect toStringz doesn't make a copy if \0 is at the end. For reference, my current approach was: auto strings = ["a", "b"]; auto c_strings = cast(char**)malloc((char*).sizeof * strings.length); for(int i; i < strings.length; i++) c_strings[i] = strings[i].ptr;What's the best way to convert char** from string[]?This is one way to do it: import std.algorithm, std.array, std.string, core.stdc.stdio; void main() { auto data = ["red", "yellow", "green"]; immutable(char)** p = array(map!toStringz(data)).ptr; printf("%s %s %s\n", p[0], p[1], p[2]); } Note: the pointer array is managed by the D GC. With DMD 2.059: immutable(char)** p = data.map!toStringz().array().ptr; Bye, bearophile
Mar 24 2012
On Sat, 24 Mar 2012 11:41:48 +0100, simendsjo <simendsjo gmail.com> wrote:On Fri, 23 Mar 2012 17:09:18 +0100, bearophile <bearophileHUGS lycos.com> wrote:Oh, I didn't find toStringz, so I turned it into: auto c_strings = strings.map!(toUTFz!(char*)).array().ptr;On Friday, 23 March 2012 at 15:48:12 UTC, simendsjo wrote:Thanks. A lot shorter and safer than my current approach. I also expect toStringz doesn't make a copy if \0 is at the end. For reference, my current approach was: auto strings = ["a", "b"]; auto c_strings = cast(char**)malloc((char*).sizeof * strings.length); for(int i; i < strings.length; i++) c_strings[i] = strings[i].ptr;What's the best way to convert char** from string[]?This is one way to do it: import std.algorithm, std.array, std.string, core.stdc.stdio; void main() { auto data = ["red", "yellow", "green"]; immutable(char)** p = array(map!toStringz(data)).ptr; printf("%s %s %s\n", p[0], p[1], p[2]); } Note: the pointer array is managed by the D GC. With DMD 2.059: immutable(char)** p = data.map!toStringz().array().ptr; Bye, bearophile
Mar 24 2012
simendsjo:Oh, I didn't find toStringz, so I turned it into:It's in std.string.auto c_strings = strings.map!(toUTFz!(char*)).array().ptr;That's wrong syntax, that 2.059head doesn't enforce yet, map needs an ending (). Bye, bearophile
Mar 24 2012
On 03/23/2012 08:48 AM, simendsjo wrote:What's the best way to convert char** from string[]?In C, char** communicates transfer of ownership. Is that what you are trying to do? Are you going to pass a slice to a C function to be filled in by that C function? Such functions usually assign to *str. In that case you can use the "make slice from raw pointer" method below. I hope others will answer my concern in the comment below: import std.stdio; import std.c.stdlib; import std.c.string; void C_func_with_an_out_parameter(char ** str) { *str = cast(char*)calloc(1, 10); (*str)[0] = 'A'; (*str)[1] = '\0'; } void main() { char * p; C_func_with_an_out_parameter(&p); char[] slice = p[0..strlen(p)]; // <-- make a D slice /* * Note: I don't think that the memory that * std.stdlib.calloc() returns is managed by the GC. For * that reason, I don't think it will be safe to share the * element with another slice and expect normal behavior * of element-sharing between slices. * * In other words, this would be risky: * * char[] anotherSlice = slice; */ writeln(slice); free(p); } Ali
Mar 23 2012
On 03/23/2012 11:23 AM, Ali Çehreli wrote:On 03/23/2012 08:48 AM, simendsjo wrote: > What's the best way to convert char** from string[]? In C, char** communicates transfer of ownership.Ok, I once again misunderstood the question. :( My question in the comment remains. Thank you, Ali
Mar 23 2012
On Fri, 23 Mar 2012 19:23:07 +0100, Ali =C3=87ehreli <acehreli yahoo.com=wrote:On 03/23/2012 08:48 AM, simendsjo wrote: > What's the best way to convert char** from string[]? In C, char** communicates transfer of ownership. Is that what you are ==trying to do? Are you going to pass a slice to a C function to be fill=ed =in by that C function? Such functions usually assign to *str. In that case you can use the ="make slice from raw pointer" method below. I hope others will answer =my =concern in the comment below: import std.stdio; import std.c.stdlib; import std.c.string; void C_func_with_an_out_parameter(char ** str) { *str =3D cast(char*)calloc(1, 10); (*str)[0] =3D 'A'; (*str)[1] =3D '\0'; } void main() { char * p; C_func_with_an_out_parameter(&p); char[] slice =3D p[0..strlen(p)]; // <-- make a D slice /* * Note: I don't think that the memory that * std.stdlib.calloc() returns is managed by the GC. For * that reason, I don't think it will be safe to share the * element with another slice and expect normal behavior * of element-sharing between slices. * * In other words, this would be risky: * * char[] anotherSlice =3D slice; */ writeln(slice); free(p); } AliI'm not sure of the semantics of the function yet. Don't know if it copi= es = the argument or stores it, if it frees it or expects me to free it :| But it's not filling the array.
Mar 24 2012