Namespaces
Variants

strncat, strncat_s

From cppreference.net
< c ‎ | string ‎ | byte
Определено в заголовочном файле <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: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

Смотрите также

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