It's so funny to read all this. In college, we were always told, "don't use strcpy! Use strncpy instead!" just to find out later on that strncpy isn't that great either. Then I heard about the better strlcpy, and even now I'm hearing that isn't quite good enough.
> It's so funny to read all this. In college, we were always told, "don't use strcpy! Use strncpy instead!" just to find out later on that strncpy isn't that great either.
TBF that was definitely incorrect, as strncpy was never intended to work with C strings. Most (though not all, that would be too easy) of the n functions work with fixed-size strings. The behaviour of strncpy makes perfect sense then.
All the str* functions work on C strings, except for strncpy. It's the only str* function which doesn't expect or produce a C string, yet its behaviour is such that it will work as if it operates on C strings in most cases.
Because strncpy's peculiarities means it acts as a conversion from a C-string to a null-padded fixed-length string, which interacts interestingly with %s: "%.*s" will stop at the first null or the provided length. If you use memcpy, you need to terminate your padded string by hand.
memcpy is more useful if your fixed-size strings are e.g. space-padded. Obviously it also works if you absolutely know your input is already a fixed-size string, but strncpy will work on both fixed-size and null-terminated inputs.