Namespaces
Variants

strncpy, strncpy_s

From cppreference.net
< c ‎ | string ‎ | byte
Определено в заголовочном файле <string.h>
(1)
char * strncpy ( char * dest, const char * src, size_t count ) ;
(до C99)
char * strncpy ( char * restrict dest, const char * restrict src, size_t count ) ;
(начиная с C99)
errno_t strncpy_s ( char * restrict dest, rsize_t destsz,
const char * restrict src, rsize_t count ) ;
(2) (начиная с C11)
1) Копирует не более count символов из массива символов, на который указывает src (включая завершающий нулевой символ, но не включая символы после нулевого символа), в массив символов, на который указывает dest .
Если count достигается до того, как весь массив src был скопирован, результирующий массив символов не завершается нулевым символом.
Если после копирования завершающего нулевого символа из src значение count не достигнуто, в dest записываются дополнительные нулевые символы до тех пор, пока не будет записано в общей сложности count символов.
Поведение не определено, если символьные массивы перекрываются, если dest или src не являются указателями на символьный массив (включая случай, когда dest или src являются нулевыми указателями), если размер массива, на который указывает dest , меньше count , или если размер массива, на который указывает src , меньше count и он не содержит нулевого символа.
2) То же, что и (1) , за исключением того, что функция не продолжает запись нулей в целевой массив для дополнения до count , она останавливается после записи завершающего нулевого символа (если в источнике не было нуля, она записывает его в dest [ count ] и затем останавливается). Кроме того, следующие ошибки обнаруживаются во время выполнения и вызывают текущую установленную функцию обработки ограничений :
  • src или dest является нулевым указателем
  • destsz равен нулю или больше RSIZE_MAX
  • count больше RSIZE_MAX
  • count больше или равен destsz , но destsz меньше или равен strnlen_s ( src, count ) , другими словами, произошло бы усечение
  • возникло бы перекрытие между исходной и целевой строками
Поведение не определено, если размер массива символов, на который указывает dest < strnlen_s ( src, destsz ) <= destsz ; другими словами, ошибочное значение destsz не выявляет надвигающееся переполнение буфера. Поведение не определено, если размер массива символов, на который указывает src < strnlen_s ( src, count ) < destsz ; другими словами, ошибочное значение count может допустить переполнение буфера.
Как и все функции с проверкой границ, strncpy_s гарантированно доступна только если __STDC_LIB_EXT1__ определено реализацией и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <string.h> .

Содержание

Параметры

dest - указатель на массив символов для копирования в
src - указатель на массив символов для копирования из
count - максимальное количество символов для копирования
destsz - размер буфера назначения

Возвращаемое значение

1) возвращает копию dest
2) возвращает ноль при успехе, возвращает ненулевое значение при ошибке. Также при ошибке записывает ноль в dest [ 0 ] (если dest не является нулевым указателем и destsz не равен нулю и не превышает RSIZE_MAX ) и может заполнить остальной массив назначения неопределенными значениями.

Примечания

Как исправлено пост-C11 DR 468, strncpy_s , в отличие от strcpy_s , разрешено перезаписывать оставшуюся часть целевого массива только при возникновении ошибки.

В отличие от strncpy , strncpy_s не заполняет конечный массив нулями. Это распространённый источник ошибок при конвертации существующего кода в версию с проверкой границ.

Хотя усечение для соответствия целевому буферу представляет собой угрозу безопасности и, следовательно, нарушение ограничений времени выполнения для strncpy_s , можно получить поведение с усечением, указав count равным размеру целевого массива минус один: функция скопирует первые count байт и добавит нулевой терминатор как обычно: strncpy_s ( dst, sizeof dst, src, ( sizeof dst ) - 1 ) ;

Пример

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
    char src[] = "hi";
    char dest[6] = "abcdef"; // нет нулевого терминатора
    strncpy(dest, src, 5); // записывает пять символов 'h', 'i', '\0', '\0', '\0' в dest
    printf("strncpy(dest, src, 5) для dest размером 6 байт дает: ");
    for (size_t n = 0; n < sizeof dest; ++n) {
        char c = dest[n];
        c ? printf("'%c' ", c) : printf("'\\0' ");
    }
    printf("\nstrncpy(dest2, src, 2) для dst размером 2 байта дает: ");
    char dest2[2];
    strncpy(dest2, src, 2); // усечение: записывает два символа 'h', 'i' в dest2
    for (size_t n = 0; n < sizeof dest2; ++n) {
        char c = dest2[n];
        c ? printf("'%c' ", c) : printf("'\\0' ");
    }
    printf("\n");
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    char dst1[6], src1[100] = "hello";
    errno_t r1 = strncpy_s(dst1, 6, src1, 100);  // записывает 0 в r1, 6 символов в dst1
    printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' в dst1
    char dst2[5], src2[7] = {'g','o','o','d','b','y','e'};
    errno_t r2 = strncpy_s(dst2, 5, src2, 7);    // копирование переполняет массив назначения
    printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // записывает ненулевое значение в r2, '\0' в dst2[0]
    char dst3[5];
    errno_t r3 = strncpy_s(dst3, 5, src2, 4);    // записывает 0 в r3, 5 символов в dst3
    printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' в dst3
#endif
}

Возможный вывод:

strncpy(dest, src, 5) для dst размером 6 байт дает: 'h' 'i' '\0' '\0' '\0' 'f'
strncpy(dest2, src, 2) для dst размером 2 байта дает: 'h' 'i'
dst1 = "hello", r1 = 0
dst2 = "", r2 = 22
dst3 = "good", r3 = 0

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.24.2.4 Функция strncpy (стр. 265)
  • K.3.7.1.4 Функция strncpy_s (стр. 447-448)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.24.2.4 Функция strncpy (стр: 363-364)
  • K.3.7.1.4 Функция strncpy_s (стр: 616-617)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.21.2.4 Функция strncpy (стр: 326-327)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.11.2.4 Функция strncpy

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

копирует одну строку в другую
(функция)
копирует один буфер в другой
(функция)
(dynamic memory TR)
выделяет копию строки до указанного размера
(функция)
C++ documentation для strncpy