strcpy, strcpy_s
From cppreference.com
| ヘッダー <string.h> で定義 |
||
| (1) | ||
| char* strcpy( char* dest, const char* src ); |
(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) と同様ですが、それ以外に、宛先配列の残りの部分を未指定の値で破壊する可能性があり、以下のエラーは実行時に検出され、現在インストールされている 制約ハンドラー関数が呼び出されます。
- src または dest がヌルポインタである
- destsz がゼロまたは RSIZE_MAX より大きい
- destsz が strnlen_s(src, destsz) 以下である。言い換えれば、切り捨てが発生する
- ソース文字列と宛先文字列の間に重複が発生する場合
dest が指す文字配列のサイズ <= strnlen_s(src, destsz) < destsz の場合、動作は未定義です。言い換えれば、destsz の誤った値は、差し迫ったバッファオーバーフローを露呈させません。
- すべての境界チェック関数と同様に、`strcpy_s` は、実装によって __STDC_LIB_EXT1__ が定義され、ユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義した場合にのみ利用可能であることが保証されます。
目次 |
[編集] パラメータ
| dest | - | 書き込み先の文字配列へのポインタ |
| src | - | コピー元のヌル終端されたバイト文字列へのポインタ |
| destsz | - | 書き込む最大文字数。通常は宛先バッファのサイズ。 |
[編集] 戻り値
1) dest のコピーを返します。
2) 成功した場合はゼロを返し、エラーの場合はゼロ以外を返します。また、エラー時には dest[0] にゼロを書き込みます(dest がヌルポインタであるか、destsz がゼロであるか、RSIZE_MAX より大きい場合を除く)。
[編集] 注釈
`strcpy_s` は、効率を向上させるために、最後に書き込まれた文字から destsz までの宛先配列を破壊することが許されています。複数バイトブロックでコピーしてから、ヌルバイトをチェックする場合があります。
関数 `strcpy_s` は BSD 関数 `strlcpy` と似ていますが、以下の点が異なります。
- `strlcpy` は、宛先に収まるようにソース文字列を切り捨てます(これはセキュリティリスクです)
- `strlcpy` は `strcpy_s` が行うすべての実行時チェックを実行しません
- `strlcpy` は、呼び出しが失敗した場合に宛先をヌル文字列に設定したり、ハンドラを呼び出したりして、失敗を明確にしません。
`strcpy_s` は潜在的なセキュリティリスクのため切り捨てを禁止していますが、代わりに境界チェックされた strncpy_s を使用して文字列を切り詰めることは可能です。
[編集] 例
このコードを実行
#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)
| |