strcpy, strcpy_s
ja.cppreference.net より
| ヘッダ <string.h>
|
||
char* strcpy( char* dest, const char* src );
|
で定義 (1) | (C99 まで) |
char* strcpy( char* restrict dest, const char* restrict src );
|
(C99 以降) | |
errno_t strcpy_s( char* restrict dest, rsize_t destsz, const char* restrict src );
|
(2) | (C11 以降) |
1)
src が指すナル終端バイト文字列(終端のナル文字を含む)を、dest が指す最初の要素を持つ文字配列にコピーします。dest 配列が十分に大きくない場合、動作は未定義です。文字列が重なる場合、動作は未定義です。dest が文字配列へのポインタでない場合、または src がナル終端バイト文字列へのポインタでない場合、動作は未定義です。2) (1) と同じですが、コピー先配列の残りを未指定の値で上書きする可能性があること、および以下のエラーが実行時に検出され、現在インストールされている 制約ハンドラ 関数を呼び出す点が異なります:
srcdestがヌルポインタであるdestszがゼロまたはRSIZE_MAXdestszより大きいstrnlen_s(src, destsz)が- 以下または等しい、つまり切り詰めが発生する
ソースとコピー先の文字列の間で重なりが発生する
dest <= strnlen_s(src, destsz) < destsz が指す文字配列のサイズよりも小さい場合、動作は未定義です。言い換えれば、誤った destsz の値は差し迫ったバッファオーバーフローを露呈しません。 すべての境界チェック付き関数と同様に、
strcpy_s が利用可能であることが保証されるのは、実装によって __STDC_LIB_EXT1__ が定義され、ユーザーが __STDC_WANT_LIB_EXT1__ をインクルードする前に整数定数 1 に定義した場合のみです。<string.h>.引数
| dest | - | 書き込み先の文字配列へのポインタ |
| src | - | コピー元のナル終端バイト文字列へのポインタ |
| destsz | - | 書き込む最大文字数。通常はコピー先バッファのサイズ |
戻り値
1)
dest のコピーを返す2)
dest[0] 成功時はゼロ、エラー時は非ゼロを返します。また、エラー時には dest にゼロを書き込みます(destsz がヌルポインタであるか、RSIZE_MAX がゼロまたは より大きい場合を除く)。
strcpy_sノートdestsz は、効率向上のために、最後に書き込まれた文字から
までコピー先配列を上書きすることが許可されています。マルチバイトブロックでコピーし、その後ナルバイトをチェックする場合があります。
strcpy_s関数 strlcpy は BSD 関数
strlcpyに似ていますが、以下の点が異なります:strlcpyはソース文字列を切り詰めてコピー先に収めます(これはセキュリティリスクです)strcpy_sはstrlcpyが行うすべての実行時チェックを実行しません
は、呼び出しが失敗した場合に、コピー先をヌル文字列に設定したり、ハンドラを呼び出したりして失敗を明確にしません。strcpy_s は潜在的なセキュリティリスクのために切り詰めを禁止していますが、境界チェック付きの strncpy を使用して文字列を切り詰めることは可能です。
例
このコードを実行する
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char* src = "Take the test.";
// src[0] = 'M' ; // this would be undefined behavior
char dst[strlen(src) + 1]; // +1 to accommodate for the null terminator
strcpy(dst, src);
dst[0] = 'M'; // OK
printf("src = %s\ndst = %s\n", src, dst);
#ifdef __STDC_LIB_EXT1__
set_constraint_handler_s(ignore_handler_s);
int r = strcpy_s(dst, sizeof dst, src);
printf("dst = \"%s\", r = %d\n", dst, r);
r = strcpy_s(dst, sizeof dst, "Take even more tests.");
printf("dst = \"%s\", r = %d\n", dst, r);
#endif
}
出力例:
src = Take the test.
dst = Make the test.
dst = "Take the test.", r = 0
dst = "", r = 22
参考文献
- C23 規格 (ISO/IEC 9899:2024):
- 7.24.2.3 The strcpy function (p: TBD)
- K.3.7.1.3 The strcpy_s function (p: TBD)
- C17 規格 (ISO/IEC 9899:2018):
- 7.24.2.3 The strcpy function (p: 264-265)
- K.3.7.1.3 The strcpy_s function (p: 447)
- C11 規格 (ISO/IEC 9899:2011):
- 7.24.2.3 The strcpy function (p: 363)
- K.3.7.1.3 The strcpy_s function (p: 615-616)
- C99 規格 (ISO/IEC 9899:1999):
- 7.21.2.3 The strcpy function (p: 326)
- C89/C90 規格 (ISO/IEC 9899:1990):
- 4.11.2.3 The strcpy function
関連項目
(C11) |
ある文字列から別の文字列へ一定数の文字をコピーする (関数) |
(C11) |
バッファを別のバッファにコピーする (関数) |
(C95)(C11) |
ワイド文字列を別のワイド文字列にコピーする (関数) |
(動的メモリ TR) |
文字列のコピーを割り当てる (関数) |
C++ ドキュメント strcpy
| |