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()を使う方法がよさそう。