strcpy, strcpy_s
From cppreference.net
|
定義先ヘッダ
<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
が指すNULL終端バイト文字列を、NULL終端文字を含めて、
dest
が指す文字配列の最初の要素にコピーします。
動作は未定義である、もし
dest
配列が十分な大きさでない場合。動作は未定義である、もし文字列が重複している場合。動作は未定義である、もし
dest
が文字配列へのポインタでないか、または
src
がヌル終端バイト文字列へのポインタでない場合。
2)
(1)
と同様ですが、以下の点が異なります:宛先配列の残りの部分を未規定の値で上書きする可能性があり、以下のエラーが実行時に検出され、現在設定されている
constraint handler
関数を呼び出します:
-
- src または dest がnullポインタである場合
- destsz がゼロまたは RSIZE_MAX より大きい場合
- destsz が strnlen_s ( src, destsz ) 以下である場合(つまり、切り捨てが発生する場合)
- ソース文字列と宛先文字列の間にオーバーラップが発生する場合
destが指す文字配列のサイズが
strnlen_s
(
src, destsz
)
未満の場合、動作は未定義である。言い換えれば、
destsz
の誤った値はバッファオーバーフローを引き起こす可能性がある。
-
すべての境界チェック付き関数と同様に、
strcpy_sは、実装によって __STDC_LIB_EXT1__ が定義されており、かつユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義している場合にのみ利用可能であることが保証される。
目次 |
パラメータ
| dest | - | 書き込み先の文字配列へのポインタ |
| src | - | コピー元のヌル終端バイト文字列へのポインタ |
| destsz | - | 書き込む最大文字数(通常は宛先バッファのサイズ) |
戻り値
1)
dest
のコピーを返す
2)
成功時はゼロを返し、エラー時は非ゼロを返します。また、エラー時には
dest
[
0
]
にゼロを書き込みます(ただし
dest
がnullポインタの場合、または
destsz
がゼロもしくは
RSIZE_MAX
より大きい場合を除く)。
注記
strcpy_s
は効率を改善するために、書き込まれた最後の文字から
destsz
までの宛先配列を破壊することが許可されています:マルチバイトブロックでコピーした後、nullバイトをチェックする可能性があります。
関数
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 strcpy関数 (p: TBD)
-
- K.3.7.1.3 strcpy_s関数 (p: TBD)
- C17規格 (ISO/IEC 9899:2018):
-
- 7.24.2.3 strcpy関数 (p: 264-265)
-
- K.3.7.1.3 strcpy_s関数 (p: 447)
- C11規格 (ISO/IEC 9899:2011):
-
- 7.24.2.3 strcpy関数 (p: 363)
-
- K.3.7.1.3 strcpy_s関数 (p: 615-616)
- C99規格 (ISO/IEC 9899:1999):
-
- 7.21.2.3 strcpy関数 (p: 326)
- C89/C90標準 (ISO/IEC 9899:1990):
-
- 4.11.2.3 strcpy関数
関連項目
|
(C11)
|
指定された文字数をある文字列から別の文字列にコピーする
(関数) |
|
(C11)
|
あるバッファから別のバッファにコピーする
(関数) |
|
(C95)
(C11)
|
ワイド文字列を別のワイド文字列にコピーする
(関数) |
|
(dynamic memory TR)
|
文字列のコピーを割り当てる
(関数) |
|
C++ documentation
for
strcpy
|
|