strncpy(3) копирование строки

Other Alias

strcpy

ОБЗОР

#include <string.h>


char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, size_t n);

ОПИСАНИЕ

Функция strcpy() копирует строку (включая завершающий нулевой байт '\0'), указанную в указателе src, в буфер, указанный в указателе dest. Строки не могут пересекаться, а строка в назначении dest должна быть достаточно большой, чтобы принять копию. Берегитесь переполнения буфера (См. ОШИБКИ)!

Функция strncpy() сходна, за исключением того, что скопировано будет только первые n байт из src. Внимание: если в первых n байт из src не окажется нулевого байта, то строка в dest также не будет завершена нулевым байтом.

Если длина src меньше n, strncpy() дописывает в dest нулевые байты, чтобы убедиться, что всего было записано n байт.

Простейшей реализацией strncpy() может быть:

char *
strncpy(char *dest, const char *src, size_t n)
{
    size_t i;
    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    for ( ; i < n; i++)
        dest[i] = '\0';
    return dest;
}

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Функции strcpy() и strncpy() возвращают указатель на скопированную строку dest.

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes(7).
ИнтерфейсАтрибутЗначение
strcpy(), strncpy() безвредность в нитяхбезвредно (MT-Safe)

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD.

ЗАМЕЧАНИЯ

Некоторые программисты считают strncpy() неэффективной и склонной к ошибкам. Если программист точно знает (в том числе с помощью проверок в коде), что размер dest больше src, то strcpy() может быть использована.

Единственным правильным (и предполагаемым) использованием strncpy() является копирование C-строки в буфер фиксированной длины с одновременной проверкой того, что буфер не переполнен и неиспользованные байты в целевом буфере обнулены (для исключения возможной утечки информации в случае, если буфер будет записан на носитель или передан другому процессу через межпроцессовое общение).

Если в первых n байт src не будет завершающего нулевого байта, strncpy() создаст ничем не ограниченную строку в dest. Если размер buf равен buflen, вы можете принудительно завершить строку с помощью следующего кода:

strncpy(buf, str, buflen - 1);
if (buflen > 0)
    buf[buflen - 1]= '\0';

Конечно же, вышеприведенный пример не учитывает того, что если размер src больше buflen - 1 байт, при копировании в dest будет потеряна часть информации.

strlcpy()

В некоторых системах (BSD, Solaris и других) есть следующая функция:


    size_t strlcpy(char *dest, const char *src, size_t size);

Эта функция подобна strncpy(), но копирует не более size-1 байт в dest, всегда добавляет конечный байт null и не дополняет назначение (помимо этого) байтами null. В данной функции исправлены некоторые проблемы strcpy() и strncpy(), но вызывающий по-прежнему должен обрабатывать возможность потери данных, если значение size окажется слишком мало. Возвращаемое значение функции — длина src, что позволяет легко обнаружить усечение: если возвращаемое значение больше или равно size, то выполнялось усечение. Если потеря данных неприемлема, то вызывающий должен или проверять аргументы перед вызовом, или проверять возвращаемое значение. Функция strlcpy() отсутствует в glibc и не стандартизована в POSIX, но доступна в Linux из библиотеки libbsd.

ДЕФЕКТЫ

Если строка назначения strcpy() недостаточно велика, то может случиться всё что угодно. Переполнение буферных строк фиксированной длины является излюбленным методом взломщиков для захвата управления машиной. Каждый раз когда программа читает или копирует данные в буфер, сначала нужно проверять достаточно ли места. Это может необязательным, если вы можете доказать, что переполнение невозможно, но будьте осторожны: со временем программы могут измениться и невозможное станет возможным.