The advice given in this article is bad. Reducing the length of the copy by one will still fail to null-terminate the string if the source exceeds the destination length. You need to add
dst[sizeof(dst)-1] = 0;
or memset the array to zero beforehand. You are not guaranteed to have a zero at the end of the input buffer otherwise (neither local variable arrays nor malloc’d arrays are guaranteed to be zeroed).strncpy sucks for a second reason: it writes n bytes no matter what the source is. That means if you write
char buffer[16384];
strncpy(buffer, “hello”, sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0;
this will fill 16K of memory with zeroes despite only needing to copy a 6-byte string.strlcpy/strlcat do the right thing (copy up to n-1 bytes and null-terminate); shame they aren’t standardized. In their absence, I suggest snprintf instead:
snprintf(buffer, sizeof(buffer), “%s”, src);
Because snprintf returns the number of bytes that would be written, it can be used to detect overlong input strings, reallocate the buffer as necessary, and also to implement efficient concatenation. It’s also surprisingly fast in most implementations.