strncpy_sはMicrosoftの拡張なので、memmoveを使った方が可搬性が良いとのことらしい。
細かいところはわかっていない。
memmoveとmemcpyの違いは、コピー元とコピー先の領域がかぶってもいいかどうかで、それ以外の挙動は同じ。
なので、かぶっても動作が担保されているmemmoveを基本的に使えばよい。
moveとついているので、コピー元が領域が担保されないように感じるがそんなことはない。
#include <stdio.h> #include <string.h> int main(void) { char dst[7]{0}; char src[] = "abcdef"; memmove(dst, src, sizeof(dst)); return 0; }
ちなみに、第三引数にdstのサイズより大きいサイズを指定すると、バッファオーバーフローが起こる(ビルド時点でわかる場合は、そもそもビルドが通らなくなる)。
一方、srcのサイズより、大きいサイズを第三引数に指定してコピーしても特に問題はない(はず)。
なので、第三引数にsizeof(dst)を指定しておけば、srcからコピーできる範囲分、dstに安全にコピーできる。
なお、dstを文字列として扱う場合、dstを事前に
char dst[7]{0};
で明示的にゼロクリアしておかないと、memmove後に、dstがヌル終端にならないケースがあるので注意。
dstを文字列として扱う場合は、ヌル終端を上書きしてしまわないように、
int main(void) { char dst[7]{0}; char src[] = "abcdef"; memmove(dst, src, sizeof(dst)-1); return 0; }
とした方がよい。
環境依存による可搬性の話を無視するなら、ヌル終端を意識するのが面倒なので、文字列コピーの場合はstrncpy_s()を使う方法がよさそう。