strlcat(), strlcpy()

Копировать или соединить строки с заданием конечного размера

Прототип:

#include <string.h>
size_t strlcpy( char *dst,
const char *src,
size_t size );
size_t strlcat( char *dst,
const char *src,
size_t size );

Аргументы:

dst
Указатель на строку назначения.
src
Указатель на исходную строку.
size
Рамер буфера назначения.

Библиотека:

libc

Описание:

Функции strlcpy() и strlcat() копируют и объединяют строки соответственно. Они разработаны, чтобы быть более безопасными, последовательными и менее подверженными ошибкам заменами для strncpy() и strncat().

В отличие от данных функций, strlcpy() и strlcat() берут полный размер буфера (а не только длину) и гарантируют NUL-терминированный результат (пока size больше 0 или, в случае strlcat(), если в dst есть хотя бы один свободный байт).


Note: Следует оставить байт для NUL в size. Также следует обратить внимание, что strlcpy() и strlcat() работают только с C-строками. Это означает, что для strlcpy() src должна завершаться NUL, а для strlcat() и src, и dst должны завершаться NUL.

Функция strlcpy() копирует до size1 символов из строки src, заканчивающейся NUL, в dst, завершая результат символом NUL.

Функция strlcat() добавляет NUL-терминированную строку src в конец dst. Она добавит не более sizestrlen( dst ) — 1 байт, завершая результат символом NUL.

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

Итоговая длина строки:


Note: Если strlcat() проходит через size символов и не находит NUL, считается, что длина строки равна size, а целевая строка не завершается NUL (поскольку не было места для NUL). Это предотвращает strlcat() от выхода за конец строки. На практике этого не должно происходить (поскольку это означает, что либо size некорректен, либо что dst не является строкой «C»). Проверка существует для предотвращения потенциальных проблем безопасности в коде.

Примеры:

Следующий фрагмент кода иллюстрирует простейший случай:

char *s, *p, buf[BUFSIZ];
...
(void)strlcpy( buf, s, sizeof( buf ) );
(void)strlcat( buf, p, sizeof( buf ) );

Чтобы обнаружить усечение строки, можно при создании пути использовать что-то наподобие этого:

char *dir, *file, pname[MAXPATHLEN];
...
if ( strlcpy( pname, dir, sizeof( pname ) ) >= sizeof( pname ) )
goto toolong;
if ( strlcat( pname, file, sizeof( pname ) ) >= sizeof( pname ) )
goto toolong;

Поскольку известно, сколько символов было скопировано в первый раз, можно немного ускорить процесс, используя копирование вместо добавления:

char *dir, *file, pname[MAXPATHLEN];
size_t n;
...
n = strlcpy( pname, dir, sizeof( pname ) );
if ( n >= sizeof( pname ) )
goto toolong;
if ( strlcpy( pname + n, file, sizeof( pname ) - n ) >= sizeof( pname ) - n )
goto toolong;

Однако можно усомниться в правильности таких оптимизаций, поскольку они сводят на нет всю задачу strlcpy() и strlcat().

Классификация:

Unix

Безопасность использования
Точка остановки потока
Нет
Обработчик прерываний
Да
Обработчик сигналов
Да
В потоке
Да

Сведения об авторах:

OpenBSD

Тематические ссылки:

snprintf(), strncpy(), strncat()




Предыдущий раздел: Описание API системной библиотеки