Thread overview
Smart way to convert a C string to a D string
Aug 07, 2013
andrea9940
Aug 07, 2013
John Colvin
Aug 08, 2013
andrea9940
Aug 10, 2013
Andrej Mitrovic
Aug 17, 2013
andrea9940
August 07, 2013
Hi, I have written a function to convert a C string to a D string.
I did not use to!string because it allocates a new string while what I want is a dynamic array of type char[] pointing to the C string.

auto cstr2dstr(inout(char)* cstr)
{
    import core.stdc.string: strlen;
    return cstr ? cstr[0 .. strlen(cstr)] : "";
}

As D newbie I'd like to know if this is the correct usage of inout (it is needed to accept without distinction char*, const(char)* and immutable(char)* right ?) and if there is already a function in the standard D library which do that conversion.
August 07, 2013
On Wednesday, 7 August 2013 at 18:50:21 UTC, andrea9940 wrote:
> Hi, I have written a function to convert a C string to a D string.
> I did not use to!string because it allocates a new string while what I want is a dynamic array of type char[] pointing to the C string.
>
> auto cstr2dstr(inout(char)* cstr)
> {
>     import core.stdc.string: strlen;
>     return cstr ? cstr[0 .. strlen(cstr)] : "";
> }
>
> As D newbie I'd like to know if this is the correct usage of inout (it is needed to accept without distinction char*, const(char)* and immutable(char)* right ?) and if there is already a function in the standard D library which do that conversion.

Another way of doing this is lazily with a range. *Very* basically done, just for char* and read-only:

struct Cstring
{
    size_t i = 0;
    char* str;

    this(char* s)
    {
        str = s;
    }

    @property bool empty()
    {
        return str[i] == '\0';
    }

    @property char front()
    {
        return str[i];
    }

    void popFront()
    {
        ++i;
    }
}
August 08, 2013
I hadn't tought of thath, thank you for the example.
August 10, 2013
On 8/7/13, andrea9940 <no@mail.plz> wrote:
> auto cstr2dstr(inout(char)* cstr)
> {
>      import core.stdc.string: strlen;
>      return cstr ? cstr[0 .. strlen(cstr)] : "";
> }

There's a small issue in your ternary operator, if 'cstr' is non-const but null, you will end up returning an immutable rather than a mutable string. In fact your return type will always be const because of this ternary (mutable and immutable both implicitly convert to const). I suggest changing it to this:

return cstr ? cstr[0 .. strlen(cstr)] : cstr[0 .. 0];

You can also use inout(char)[] on the return type, it documents the
function better (and this is how I caught the ternary issue as well).
August 17, 2013
Excellent discovery !