On Monday, 1 November 2021 at 19:56:13 UTC, pascal111 wrote:
But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length:

{

char[] s="xyz".dup;

strcpy(&s[0], "Hello World!");

writeln(s);

}

Result:

Hel

Easy win: use normal operations with static arrays instead of strcpy:

```d
unittest {
    char[3] s = "xyz";
s = "Hello World"; // Error: index [11] exceeds array of length 3
}
```

Now you'll get errors (in range-checked builds) instead of silent bad behavior.

With a larger buffer, short assigns (only with string literals) zero the rest of the buffer:

```d
unittest {
    char[15] s = "xyz";
    s = "Hello World"; // this is OK
    assert(s == "Hello World\0\0\0\0");
}

unittest {
    char[15] s = "Hello World";
    s = "xyz"; // so is this
    assert(s[0 .. 5] == "xyz\0\0");
}
```

But more realistically you'll be getting strings from somewhere and can assign a specific region using the length of those strings:

```d
unittest {
    // pretend these are user inputs
    string ex1 = "Hello World";
    string ex2 = "xyz";

    char[15] s;

    s[0 .. ex1.length] = ex1;
    assert(s == "Hello World\xFF\xFF\xFF\xFF");
    s[0 .. ex2.length] = ex2;
    assert(s[0 .. ex1.length] == "xyzlo World");
}
```

This is all obviously much more of a hassle than normal D string-handling, but if you're going to apply C levels of care with memory and string handling, you can do that in D while still avoiding C levels of bugs.

```d
unittest {
    import std.algorithm : min;
    import core.stdc.string : strlen;

    char[6] buf;
    string output;

    foreach (input; ["ok", "Way too long!"]) {
        auto len = min(buf.length-1, input.length);
        buf[0 .. len] = input[0 .. len];
        buf[len] = '\0';
        output ~= buf[0 .. len+1];
    }
    assert(output == "ok\0Way t\0");
    assert(output[0 .. strlen(&output[0])] == "ok");
}
```

Reply via email to