strncat, strncat_s
Из ru.cppreference.net
| Определён в заголовке <string.h>
|
||
char* strncat( char* dest, const char* src, size_t count );
|
(1) | (до 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 <stdio.h>
#include <stdlib.h>
#include <string.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
strcat_s |
(C11) конкатенирует две строки |
strcpy_s |
(C11) копирует одну строку в другую |
memccpy |
(C23) копирует один буфер в другой, останавливаясь после указанного разделителя |
(функция)Документация по C++ для
| |