Jump to page: 1 2
Thread overview
Printing a C "string" with write(f)ln
Feb 09, 2016
Whirlpool
Feb 09, 2016
Jakob Ovrum
Feb 09, 2016
Gary Willoughby
Feb 09, 2016
Daniel Kozak
Feb 09, 2016
Daniel Kozak
Feb 09, 2016
Gary Willoughby
Feb 09, 2016
Jakob Ovrum
Feb 09, 2016
Gary Willoughby
Feb 10, 2016
Jakob Ovrum
Feb 10, 2016
Gary Willoughby
Feb 09, 2016
y
Feb 09, 2016
Daniel Kozak
February 09, 2016
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
February 09, 2016
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
February 09, 2016
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:
http://dlang.org/phobos/std_string.html#.fromStringz

import std.string;
string dstring = my_c_string.fromStringz;

February 09, 2016
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

http://dlang.org/phobos/std_string.html#.fromStringz

February 09, 2016
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));
February 09, 2016
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
February 09, 2016
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

February 09, 2016
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
}
February 09, 2016
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.
February 09, 2016
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.
« First   ‹ Prev
1 2