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
символов из массива символов, на который указывает
src
, останавливаясь при обнаружении нулевого символа, в конец строки байтов с нулевым завершением, на которую указывает
dest
. Символ
src
[
0
]
заменяет нулевой терминатор в конце
dest
. Завершающий нулевой символ всегда добавляется в конце (таким образом, максимальное количество байтов, которое функция может записать, составляет
count
+
1
).
dest
, так и первых
count
символов
src
, плюс завершающий нулевой символ. Поведение не определено, если исходный и целевой объекты перекрываются. Поведение не определено, если
dest
не является указателем на байтовую строку с нулевым завершением или
src
не является указателем на массив символов.
destsz
), и что следующие ошибки обнаруживаются во время выполнения и вызывают установленную в данный момент
функцию обработки ограничений
:
-
-
srcилиdestявляется нулевым указателем -
destszилиcountравен нулю или превышает RSIZE_MAX -
в первых
destszбайтахdestотсутствует нулевой символ -
произойдет усечение:
countили длинаsrc(в зависимости от того, что меньше) превышает доступное пространство между нулевым терминаторомdestиdestsz. - произойдет перекрытие исходной и целевой строк
-
dest
<
strnlen
(
dest,destsz
)
+
strnlen
(
src,count
)
+
1
<
destsz
; другими словами, ошибочное значение
destsz
не выявляет надвигающееся переполнение буфера. Поведение не определено, если размер символьного массива, на который указывает
src
<
strnlen
(
src,count
)
<
destsz
; другими словами, ошибочное значение
count
не выявляет надвигающееся переполнение буфера.
-
Как и все функции с проверкой границ,
strncat_sгарантированно доступна только если реализация определяет __STDC_LIB_EXT1__ и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <string.h> .
Содержание |
Параметры
| dest | - | указатель на нуль-терминированную байтовую строку для добавления |
| src | - | указатель на массив символов для копирования |
| count | - | максимальное количество символов для копирования |
| destsz | - | размер буфера назначения |
Возвращаемое значение
dest
dest
не является нулевым указателем или
destsz
не равен нулю или не больше
RSIZE_MAX
).
Примечания
Поскольку
strncat
необходимо находить конец
dest
при каждом вызове, использование
strncat
для конкатенации множества строк в одну является неэффективным.
Хотя усечение для соответствия целевому буферу представляет собой угрозу безопасности и, следовательно, нарушение ограничений времени выполнения для
strncat_s
, можно получить поведение с усечением, указав
count
равным размеру целевого массива минус один: функция скопирует первые
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 (стр: 379)
-
- K.3.7.2.2 Функция strncat_s (стр: TBD)
- Стандарт C17 (ISO/IEC 9899:2018):
-
- 7.24.3.2 Функция strncat (стр: 265-266)
-
- K.3.7.2.2 Функция strncat_s (стр: 449-450)
- Стандарт C11 (ISO/IEC 9899:2011):
-
- 7.24.3.2 Функция strncat (стр: 364-365)
-
- K.3.7.2.2 Функция strncat_s (стр: 618-620)
- Стандарт C99 (ISO/IEC 9899:1999):
-
- 7.21.3.2 Функция strncat (стр: 327-328)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
-
- 4.11.3.2 Функция strncat
Смотрите также
|
(C11)
|
объединяет две строки
(функция) |
|
(C11)
|
копирует одну строку в другую
(функция) |
|
(C23)
|
копирует один буфер в другой, останавливаясь после указанного разделителя
(функция) |
|
C++ documentation
для
strncat
|
|