Spec-Zone.ru › C

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).
Поведение не определено, если в массиве назначения недостаточно места для содержимого 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

См. также

strcatstrcat_s
(C11)
объединяет две строки
(функция)
strcpystrcpy_s
(C11)
копирует одну строку в другую
(функция)
memccpy
(C23)
копирует один буфер в другой, останавливаясь после указанного разделителя
(функция)
Документация C++ для strncat

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/string/byte/strncat

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API