www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Printing a C "string" with write(f)ln

reply Whirlpool <whirlpool cloudy.sky> writes:
Hello,

When you are using a C function (from an external library) that 
returns a pointer on char which is the beginning of a string (I 
know that C does not have a string type, that they are just 
arrays of chars ended by '\0'), is there a simple way to print 
that string with D's write(f)ln, should I use C's printf, or 
something else ? What is the best way ? Because if I do
writefln("... %s", *pString);
it only displays the first character of the string, the value 
that pString points to

Thanks
Feb 09 2016
next sibling parent reply Jakob Ovrum <jakobovrum gmail.com> writes:
On Tuesday, 9 February 2016 at 12:46:59 UTC, Whirlpool wrote:
 Hello,

 When you are using a C function (from an external library) that 
 returns a pointer on char which is the beginning of a string (I 
 know that C does not have a string type, that they are just 
 arrays of chars ended by '\0'), is there a simple way to print 
 that string with D's write(f)ln, should I use C's printf, or 
 something else ? What is the best way ? Because if I do
 writefln("... %s", *pString);
 it only displays the first character of the string, the value 
 that pString points to

 Thanks
writefln et al sensibly does *not* assume that a pointer to char is a C string, for memory safety purposes. Print the result of std.string.fromStringz[1] instead: writeln(fromStringz(pString)); writefln("%s", fromStringz(pString)); [1] http://dlang.org/phobos/std_string#fromStringz
Feb 09 2016
parent reply Gary Willoughby <dev nomad.so> writes:
On Tuesday, 9 February 2016 at 12:50:27 UTC, Jakob Ovrum wrote:
 writefln et al sensibly does *not* assume that a pointer to 
 char is a C string, for memory safety purposes.

 Print the result of std.string.fromStringz[1] instead:

 writeln(fromStringz(pString));
 writefln("%s", fromStringz(pString));

 [1] http://dlang.org/phobos/std_string#fromStringz
Or use `to` like this: import std.conv; writefln("%s", pString.to!(string));
Feb 09 2016
next sibling parent reply Daniel Kozak <kozzi11 gmail.com> writes:
On Tuesday, 9 February 2016 at 16:52:09 UTC, Gary Willoughby 
wrote:
 On Tuesday, 9 February 2016 at 12:50:27 UTC, Jakob Ovrum wrote:
 writefln et al sensibly does *not* assume that a pointer to 
 char is a C string, for memory safety purposes.

 Print the result of std.string.fromStringz[1] instead:

 writeln(fromStringz(pString));
 writefln("%s", fromStringz(pString));

 [1] http://dlang.org/phobos/std_string#fromStringz
Or use `to` like this: import std.conv; writefln("%s", pString.to!(string));
this will allocate new string which can be performance problem. Maybe: writefln("%s", pString.to!(char[])); But I do not know if this works and does not allocate
Feb 09 2016
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
On Tuesday, 9 February 2016 at 16:58:03 UTC, Daniel Kozak wrote:
 On Tuesday, 9 February 2016 at 16:52:09 UTC, Gary Willoughby 
 wrote:
 On Tuesday, 9 February 2016 at 12:50:27 UTC, Jakob Ovrum wrote:
 writefln et al sensibly does *not* assume that a pointer to 
 char is a C string, for memory safety purposes.

 Print the result of std.string.fromStringz[1] instead:

 writeln(fromStringz(pString));
 writefln("%s", fromStringz(pString));

 [1] http://dlang.org/phobos/std_string#fromStringz
Or use `to` like this: import std.conv; writefln("%s", pString.to!(string));
this will allocate new string which can be performance problem. Maybe: writefln("%s", pString.to!(char[])); But I do not know if this works and does not allocate
void main() { char[] chars = cast(char[])"Ahoj svete"; char* cstr = chars.ptr; auto s1 = to!string(cstr); auto s2 = to!(char[])(cstr); auto s3 = fromStringz(cstr); writeln(cstr); //46D310 writeln(s1.ptr); //7F0062EF1000 writeln(s2.ptr); //7F0062EF1010 writeln(s3.ptr); //46D310 }
Feb 09 2016
prev sibling parent Gary Willoughby <dev nomad.so> writes:
On Tuesday, 9 February 2016 at 16:58:03 UTC, Daniel Kozak wrote:
 Or use `to` like this:

 import std.conv;
 writefln("%s", pString.to!(string));
this will allocate new string which can be performance problem.
Which is good in most cases. It's better to have the GC take care of the D string instead of worrying about the lifetime of pString.
Feb 09 2016
prev sibling parent reply Jakob Ovrum <jakobovrum gmail.com> writes:
On Tuesday, 9 February 2016 at 16:52:09 UTC, Gary Willoughby 
wrote:
 On Tuesday, 9 February 2016 at 12:50:27 UTC, Jakob Ovrum wrote:
 writefln et al sensibly does *not* assume that a pointer to 
 char is a C string, for memory safety purposes.

 Print the result of std.string.fromStringz[1] instead:

 writeln(fromStringz(pString));
 writefln("%s", fromStringz(pString));

 [1] http://dlang.org/phobos/std_string#fromStringz
Or use `to` like this: import std.conv; writefln("%s", pString.to!(string));
to!string behaving like that was a poor design choice[1]. Please use fromStringz. [1] https://github.com/D-Programming-Language/phobos/pull/1607
Feb 09 2016
parent reply Gary Willoughby <dev nomad.so> writes:
On Tuesday, 9 February 2016 at 17:02:28 UTC, Jakob Ovrum wrote:
 to!string behaving like that was a poor design choice[1]. 
 Please use fromStringz.

 [1] https://github.com/D-Programming-Language/phobos/pull/1607
It's not a poor design choice. It ensures the string is handled by the D GC instead of the C side freeing it. `fromStringz` and `to!(String)` are for different cases.
Feb 09 2016
parent reply Jakob Ovrum <jakobovrum gmail.com> writes:
On Tuesday, 9 February 2016 at 22:39:14 UTC, Gary Willoughby 
wrote:
 On Tuesday, 9 February 2016 at 17:02:28 UTC, Jakob Ovrum wrote:
 to!string behaving like that was a poor design choice[1]. 
 Please use fromStringz.

 [1] https://github.com/D-Programming-Language/phobos/pull/1607
It's not a poor design choice. It ensures the string is handled by the D GC instead of the C side freeing it. `fromStringz` and `to!(String)` are for different cases.
You clearly didn't read the discussion in the link. And, when copying is desired, I'll take fromStringz(cstr).idup over to!string any day.
Feb 09 2016
parent Gary Willoughby <dev nomad.so> writes:
On Wednesday, 10 February 2016 at 07:20:03 UTC, Jakob Ovrum wrote:
 You clearly didn't read the discussion in the link.
I did and I fully agree with jmdavis.
Feb 10 2016
prev sibling next sibling parent y <y srtnwz.com> writes:
On Tuesday, 9 February 2016 at 12:46:59 UTC, Whirlpool wrote:
 Hello,

 When you are using a C function (from an external library) that 
 returns a pointer on char which is the beginning of a string (I 
 know that C does not have a string type, that they are just 
 arrays of chars ended by '\0'), is there a simple way to print 
 that string with D's write(f)ln, should I use C's printf, or 
 something else ? What is the best way ? Because if I do
 writefln("... %s", *pString);
 it only displays the first character of the string, the value 
 that pString points to

 Thanks
sure: import std.string; string dstring = my_c_string.fromStringz;
Feb 09 2016
prev sibling parent Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
V Tue, 09 Feb 2016 12:46:59 +0000
Whirlpool via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
napsáno:

 Hello,
 
 When you are using a C function (from an external library) that 
 returns a pointer on char which is the beginning of a string (I 
 know that C does not have a string type, that they are just 
 arrays of chars ended by '\0'), is there a simple way to print 
 that string with D's write(f)ln, should I use C's printf, or 
 something else ? What is the best way ? Because if I do
 writefln("... %s", *pString);
 it only displays the first character of the string, the value 
 that pString points to
 
 Thanks
Feb 09 2016