strncat, strncat_s
Определено в заголовочном файле <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).
Поведение не определено, если в массиве назначения недостаточно места для содержимого
2) То же, что и (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 | - | размер буфера назначения |
Возвращаемое значение
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
См. также
|
(C11) | объединяет две строки (функция) |
|
(C11) | копирует одну строку в другую (функция) |
|
(C23) | копирует один буфер в другой, останавливаясь после указанного разделителя (функция) |
Документация C++ для strncat |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/string/byte/strncat