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:
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:
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:
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.
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");
}