strncat, strncat_s
Defined in header <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) |
1) Присоединяет не более
count символов из символьного массива, на который указывает src, останавливаясь, если найден нулевой символ, к концу нуль-терминированной строке байтов, на которую указывает dest. Символ src[0] заменяет нулевой терминатор в конце dest. Заключительный нулевой символ всегда добавляется в конце (поэтому максимальное количество байтов, которые может записать функция, составляет count+1).
Поведение не определено, если целевой массив не имеет достаточного места для содержимого как
dest, так и первых count символов src, плюс заключительный нулевой символ. Поведение не определено, если исходный и целевой объекты перекрываются. Поведение не определено, если dest не является указателем на нуль-терминированную строку байтов или src не является указателем на массив символов.
2) То же, что и (1), за исключением того, что эта функция может перезаписать остальную часть целевого массива (с последнего записанного байта до
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 | - | размер целевого буфера |
Возвращаемое значение
1) возвращает копию
dest
2) возвращает ноль при успехе, возвращает ненулевое значение при ошибке. Также при ошибке записывает ноль в
dest[0] (если 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:2023):
- 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++ для strncat |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/string/byte/strncat