Поделиться через


strncpy, _strncpy_l, wcsncpy, _wcsncpy_l, _mbsncpy, _mbsncpy_l

Копируют символы одной строки в другую. Доступны более безопасные версии этих функций; seestrncpy_s, _strncpy_s_l_mbsncpy_s_lwcsncpy_s_mbsncpy_s_wcsncpy_s_l.

Важно!

Функции _mbsncpy и _mbsncpy_l не могут использоваться в приложениях, запускаемых в среде выполнения Windows. Дополнительные сведения: Функции CRT, которые не поддерживаются в приложениях универсальной платформы Windows.

Синтаксис

char *strncpy(
   char *strDest,
   const char *strSource,
   size_t count
);
char *_strncpy_l(
   char *strDest,
   const char *strSource,
   size_t count,
   _locale_t locale
);
wchar_t *wcsncpy(
   wchar_t *strDest,
   const wchar_t *strSource,
   size_t count
);
wchar_t *_wcsncpy_l(
   wchar_t *strDest,
   const wchar_t *strSource,
   size_t count,
   _locale_t locale
);
unsigned char *_mbsncpy(
   unsigned char *strDest,
   const unsigned char *strSource,
   size_t count
);
unsigned char *_mbsncpy_l(
   unsigned char *strDest,
   const unsigned char *strSource,
   size_t count,
   _locale_t locale
);
template <size_t size>
char *strncpy(
   char (&strDest)[size],
   const char *strSource,
   size_t count
); // C++ only
template <size_t size>
char *_strncpy_l(
   char (&strDest)[size],
   const char *strSource,
   size_t count,
   _locale_t locale
); // C++ only
template <size_t size>
wchar_t *wcsncpy(
   wchar_t (&strDest)[size],
   const wchar_t *strSource,
   size_t count
); // C++ only
template <size_t size>
wchar_t *_wcsncpy_l(
   wchar_t (&strDest)[size],
   const wchar_t *strSource,
   size_t count,
   _locale_t locale
); // C++ only
template <size_t size>
unsigned char *_mbsncpy(
   unsigned char (&strDest)[size],
   const unsigned char *strSource,
   size_t count
); // C++ only
template <size_t size>
unsigned char *_mbsncpy_l(
   unsigned char (&strDest)[size],
   const unsigned char *strSource,
   size_t count,
   _locale_t locale
); // C++ only

Параметры

strDest
Конечная строка.

strSource
Исходная строка.

count
Число копируемых символов.

locale
Используемый языковой стандарт.

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

Возвращает strDest. Нет зарезервированных возвращаемых значений для указания ошибки.

Замечания

Функция strncpy копирует первые несколько символов, количество которых определяет параметр count, из строки strSource в строку strDest и возвращает строку strDest. Если count длина меньше или равна длине strSource, значение NULL не добавляется автоматически к скопированной строке. Если значение count больше, чем длина строки strSource, строка назначения заполняется символами null, пока ее длина не достигнет длины строки count. При перекрытии исходного и конечного буферов поведение strncpy не определено.

Важно!

strncpy не проверяет, достаточно ли места в строке strDest, в связи с чем может возникнуть ошибка переполнения буфера. Аргумент count ограничивает количество копируемых символов, но не влияет на размер strDest. См. следующий пример. Дополнительные сведения см. в разделе "Избегание переполнения буфера".

Если strDest или strSource является NULL указателем или count меньше или равно нулю, вызывается обработчик недопустимых параметров, как описано в разделе проверки параметров. Если разрешается продолжать выполнение, эти функции возвращают -1 и задают errno значение EINVAL.

Функции wcsncpy и _mbsncpy являются версиями функции strncpy для расширенных и многобайтовых символов. Аргументы и возвращаемое значение функций wcsncpy и _mbsncpy различаются соответственно. В остальном эти шесть функций ведут себя идентично.

Версии этих функций с суффиксом _l идентичны, за исключением того, что для поведения, зависящего от языкового стандарта, они используют переданный параметр языкового стандарта вместо текущего языкового стандарта. Дополнительные сведения см. в разделе Locale.

В C++ эти функции имеют шаблонные перегрузки, которые вызывают более новые и безопасные аналоги этих функций. Дополнительные сведения см. в разделе "Безопасные перегрузки шаблонов".

По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это поведение, см . статью "Глобальное состояние" в CRT.

Сопоставления подпрограмм универсального текста

TCHAR.H Обычной _UNICODE и _MBCS не определен _MBCS Определенные _UNICODE Определенные
_tcsncpy strncpy _mbsnbcpy wcsncpy
_tcsncpy_l _strncpy_l _mbsnbcpy_l _wcsncpy_l

Примечание.

Функции _strncpy_l и _wcsncpy_l не зависят от языкового стандарта; они предназначены только для функции _tcsncpy_l и не должны вызываться напрямую.

Требования

Маршрут Обязательный заголовок
strncpy <string.h>
wcsncpy <string.h> или <wchar.h>
_mbsncpy, _mbsncpy_l <mbstring.h>

Дополнительные сведения о совместимости платформ см. в разделе "Совместимость".

Пример

В следующем примере показано использование процедуры strncpy и способ ее ошибочного применения, вызывающий ошибки и проблемы безопасности. Компилятор создает предупреждение для каждого вызова strncpy , аналогичного crt_strncpy_x86.c(15) : предупреждение C4996: 'strncpy': эта функция или переменная могут быть небезопасными. Вместо этого рекомендуется использовать strncpy_s . Чтобы отключить нерекомендуемую функцию, используйте _CRT_SECURE_NO_WARNINGS. Дополнительные сведения см. в справке по Интернету.

// crt_strncpy_x86.c
// Use this command in an x86 developer command prompt to compile:
// cl /TC /W3 crt_strncpy_x86.c

#include <stdio.h>
#include <string.h>

int main() {
   char t[20];
   char s[20];
   char *p = 0, *q = 0;

   strcpy_s(s, sizeof(s), "AA BB CC");
   // Note: strncpy is deprecated; consider using strncpy_s instead
   strncpy(s, "aa", 2);     // "aa BB CC"         C4996
   strncpy(s + 3, "bb", 2); // "aa bb CC"         C4996
   strncpy(s, "ZZ", 3);     // "ZZ",              C4996
                            // count greater than strSource, null added
   printf("%s\n", s);

   strcpy_s(s, sizeof(s), "AA BB CC");
   p = strstr(s, "BB");
   q = strstr(s, "CC");
   strncpy(s, "aa", p - s - 1);   // "aa BB CC"   C4996
   strncpy(p, "bb", q - p - 1);   // "aa bb CC"   C4996
   strncpy(q, "cc",  q - s);      // "aa bb cc"   C4996
   strncpy(q, "dd", strlen(q));   // "aa bb dd"   C4996
   printf("%s\n", s);

   // some problems with strncpy
   strcpy_s(s, sizeof(s), "test");
   strncpy(t, "this is a very long string", 20 ); // C4996
   // Danger: at this point, t has no terminating null,
   // so the printf continues until it runs into one.
   // In this case, it will print "this is a very long test"
   printf("%s\n", t);

   strcpy_s(t, sizeof(t), "dogs like cats");
   printf("%s\n", t);

   strncpy(t + 10, "to chase cars.", 14); // C4996
   printf("%s\n", t);

   // strncpy has caused a buffer overrun and corrupted string s
   printf("Buffer overrun: s = '%s' (should be 'test')\n", s);
   // Since the stack grows from higher to lower addresses, buffer
   // overruns can corrupt function return addresses on the stack,
   // which can be exploited to run arbitrary code.
}

Выходные данные

ZZ
aa bb dd
this is a very long test
dogs like cats
dogs like to chase cars.
Buffer overrun: s = 'ars.' (should be 'test')

Макет автоматических переменных и уровень обнаружения ошибок и защиты кода могут варьироваться в зависимости от изменения в параметрах компилятора. Данный пример может дать иные результаты, если построить его в другой среде компиляции или с другими параметрами компилятора.

См. также

Обработка строк
Локаль
Интерпретация последовательностей многобайтовых символов
_mbsnbcpy, _mbsnbcpy_l
strcat, wcscat, _mbscat
strcmp, wcscmp, _mbscmp
strcpy, wcscpy, _mbscpy
strncat, _strncat_l, wcsncat, _wcsncat_l, _mbsncat, _mbsncat_l
strncmp, wcsncmp, _mbsncmp, _mbsncmp_l
_strnicmp, _wcsnicmp, _mbsnicmp, _strnicmp_l, _wcsnicmp_l, _mbsnicmp_l
strrchr, wcsrchr, _mbsrchr, _mbsrchr_l
_strset, _strset_l, _wcsset, _wcsset_l, _mbsset, _mbsset_l
strspn, wcsspn, _mbsspn, _mbsspn_l
strncpy_s, _strncpy_s_l, wcsncpy_s, _wcsncpy_s_l, _mbsncpy_s, _mbsncpy_s_l
strcpy_s, wcscpy_s, _mbscpy_s