#include <string.h> char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n);
strncpy() 関数も同様だが、 src のうち最大でも n バイトしかコピーされない点が異なる。 警告: src の最初の n バイトの中にヌルバイトがない場合、 dest に格納される文字列はヌルで終端されないことになる。
src の長さが n よりも短い場合、 strncpy() は dest に追加のヌルバイトを書き込み、全部で n バイトが書き込まれるようにする。
strncpy() の簡単な実装は以下のような感じであろう:
char *
strncpy(char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for ( ; i < n; i++)
dest[i] = '\0';
インターフェース | 属性 | 値 |
strcpy(), strncpy() | Thread safety | MT-Safe |
strncpy() の正しい (かつ意図された) 用途は、 C 文字列の固定長バッファーへのコピーを、 バッファーがオーバーフローしないことと、 宛先バッファーの未使用バイトが 0 で埋められることの両方を保証しつつ行うことである。 (宛先バッファーを 0 で埋めるのは、 たいていの場合、 バッファーを媒体に書き込んだり、別のプロセスにプロセス間通信を用いて送信したりした場合に情報洩れを防ぐためである)。
src の最初の n バイトに終端のヌルバイトがない場合、 strncpy() は dest に終端されていない文字列を生成する。 buf の長さが buflen の場合、以下のようにして強制的に終端することができる。
if (buflen > 0) {
strncpy(buf, str, buflen - 1);
buf[buflen - 1]= '\0';
}
(もちろん、上記の方法では、 src に入っている情報が buflen - 1 バイトよりも多い場合には、 dest へのコピー時に情報が失われるという事実は無視している。)
size_t strlcpy(char *dest, const char *src, size_t size);
この関数は strncpy() と同様だが、 最大でも size-1 バイトしか dest にコピーをせず、 末尾への終端のヌルバイトの追加が必ず行われ、 宛先バッファー (の未使用部分) へのヌルバイトの書き込みが行われない。 この関数では strcpy() や strncpy() の持つ問題のいくつかが修正されているが、 size が小さすぎた場合にはデータが失われる問題には、 依然として呼び出し側で対処する必要がある。 この関数の返り値は src の長さである。 これにより、 末尾の切り詰めが行われたかを簡単に検出することができる。 返り値が size 以上の場合には、 末尾の切り詰めが発生している。 データロスが問題となる場合は、 呼び出し側で、 呼び出し前に引数をチェックするか、 この関数の返り値を検査するかのいずれかをしなければならない。 strlcpy() は glibc には存在せず、 POSIX による標準化もされていないが、 Linux では libbsd ライブラリ経由で利用できる。