strncat, strncat_s
|
ヘッダーで定義
<string.h>
|
||
| (1) | ||
|
char
*
strncat
(
char
*
dest,
const
char
*
src,
size_t
count
)
;
|
(C99まで) | |
|
char
*
strncat
(
char
*
restrict
dest,
const
char
*
restrict
src,
size_t
count
)
;
|
(C99以降) | |
|
errno_t strncat_s
(
char
*
restrict
dest, rsize_t destsz,
const char * restrict src, rsize_t count ) ; |
(2) | (C11以降) |
count
文字を、null文字が見つかると停止しながら、
src
が指す文字配列から、
dest
が指すnull終端バイト文字列の末尾に追加します。文字
src
[
0
]
は
dest
の末尾のnull終端文字を置き換えます。終端のnull文字は常に最後に追加されます(したがって、この関数が書き込む可能性のある最大バイト数は
count
+
1
です)。
dest
と
src
の最初の
count
文字、および終端ナル文字の両方の内容を格納するのに十分な領域を持たない場合、動作は未定義です。ソースオブジェクトと宛先オブジェクトがオーバーラップする場合、動作は未定義です。
dest
がナル終端バイト文字列へのポインタでない場合、または
src
が文字配列へのポインタでない場合、動作は未定義です。
destsz
まで)を破壊する可能性があり、以下のエラーが実行時に検出され、現在インストールされている
constraint handler
関数を呼び出す点が異なります:
-
-
srcまたはdestがnullポインタである -
destszまたはcountがゼロまたは RSIZE_MAX より大きい -
destの最初のdestszバイトにnull文字が存在しない -
切り捨てが発生する場合:
countまたはsrcの長さ(いずれか小さい方)が、destのnull終端文字とdestszの間に利用可能な領域を超える - ソース文字列と宛先文字列の間にオーバーラップが発生する場合
-
dest
が指す文字配列のサイズが
strnlen
(
dest,destsz
)
+
strnlen
(
src,count
)
+
1
<
destsz
の場合、動作は未定義です。言い換えれば、
destsz
の誤った値は差し迫ったバッファオーバーフローを露呈しません。
src
が指す文字配列のサイズが
strnlen
(
src,count
)
<
destsz
の場合、動作は未定義です。言い換えれば、
count
の誤った値は差し迫ったバッファオーバーフローを露呈しません。
-
すべての境界チェック付き関数と同様に、
strncat_sは、実装によって __STDC_LIB_EXT1__ が定義されており、かつユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義している場合にのみ利用可能であることが保証されます。
目次 |
パラメータ
| dest | - | 追加先のヌル終端バイト文字列へのポインタ |
| src | - | コピー元の文字配列へのポインタ |
| count | - | コピーする最大文字数 |
| destsz | - | 宛先バッファのサイズ |
戻り値
dest
のコピーを返す
dest
がnullポインタの場合、または
destsz
がゼロまたは
RSIZE_MAX
より大きい場合は除く)。
注記
strncat
は各呼び出しで
dest
の終端を検索する必要があるため、
strncat
を使用して多くの文字列を1つに連結するのは非効率的です。
宛先バッファに合わせた切り詰めはセキュリティリスクであるため、
strncat_s
の実行時制約違反となりますが、
count
を宛先配列のサイズから1を引いた値に指定することで、切り詰め動作を実現することが可能です。これは常に最初の
count
バイトをコピーし、ヌル終端文字を追加します:
strncat_s
(
dst,
sizeof
dst, src,
(
sizeof
dst
)
-
strnlen_s
(
dst,
sizeof
dst
)
-
1
)
;
例
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> #include <stdio.h> #include <stdlib.h> int main(void) { char str[50] = "Hello "; char str2[50] = "World!"; strcat(str, str2); strncat(str, " Goodbye World!", 3); puts(str); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char s1[100] = "good"; char s5[1000] = "bye"; int r1 = strncat_s(s1, 100, s5, 1000); // r1 is 0, s1 holds "goodbye\0" printf("s1 = %s, r1 = %d\n", s1, r1); char s2[6] = "hello"; int r2 = strncat_s(s2, 6, "", 1); // r2 is 0, s2 holds "hello\0" printf("s2 = %s, r2 = %d\n", s2, r2); char s3[6] = "hello"; int r3 = strncat_s(s3, 6, "X", 2); // r3 is non-zero, s3 holds "\0" printf("s3 = %s, r3 = %d\n", s3, r3); // the strncat_s truncation idiom: char s4[7] = "abc"; int r4 = strncat_s(s4, 7, "defghijklmn", 3); // r4 is 0, s4 holds "abcdef\0" printf("s4 = %s, r4 = %d\n", s4, r4); #endif }
出力例:
Hello World! Go s1 = goodbye, r1 = 0 s2 = hello, r2 = 0 s3 = , r3 = 22 s4 = abcdef, r4 = 0
参考文献
- C23規格 (ISO/IEC 9899:2024):
-
- 7.26.3.2 strncat関数 (p: 379)
-
- K.3.7.2.2 strncat_s関数 (p: TBD)
- C17規格 (ISO/IEC 9899:2018):
-
- 7.24.3.2 strncat関数 (p: 265-266)
-
- K.3.7.2.2 strncat_s関数 (p: 449-450)
- C11規格 (ISO/IEC 9899:2011):
-
- 7.24.3.2 strncat関数 (p: 364-365)
-
- K.3.7.2.2 strncat_s関数 (p: 618-620)
- C99規格 (ISO/IEC 9899:1999):
-
- 7.21.3.2 strncat関数 (p: 327-328)
- C89/C90標準 (ISO/IEC 9899:1990):
-
- 4.11.3.2 strncat関数
関連項目
|
(C11)
|
二つの文字列を連結する
(関数) |
|
(C11)
|
文字列を別の文字列にコピーする
(関数) |
|
(C23)
|
一つのバッファを別のバッファにコピーし、指定された区切り文字の後で停止する
(関数) |
|
C++ documentation
for
strncat
|
|