strncpy_s、_strncpy_s_l、wcsncpy_s、_wcsncpy_s_l、_mbsncpy_s、_mbsncpy_s_lstrncpy_s, _strncpy_s_l, wcsncpy_s, _wcsncpy_s_l, _mbsncpy_s, _mbsncpy_s_l

将一个字符串的字符复制到另一个字符串。Copies characters of one string to another. 这些版本的 strncpy、_strncpy_l、wcsncpy、_wcsncpy_l、_mbsncpy、_mbsncpy_l 具有安全性增强功能,如 CRT 中的安全性功能中所述。These versions of strncpy, _strncpy_l, wcsncpy, _wcsncpy_l, _mbsncpy, _mbsncpy_l have security enhancements, as described in Security Features in the CRT.

重要

_mbsncpy_s_mbsncpy_s_l不能用于在 Windows 运行时中执行的应用程序。_mbsncpy_s and _mbsncpy_s_l cannot be used in applications that execute in the Windows Runtime. 有关详细信息,请参阅通用 Windows 平台应用中不支持的 CRT 函数For more information, see CRT functions not supported in Universal Windows Platform apps.

语法Syntax

errno_t strncpy_s(
   char *strDest,
   size_t numberOfElements,
   const char *strSource,
   size_t count
);
errno_t _strncpy_s_l(
   char *strDest,
   size_t numberOfElements,
   const char *strSource,
   size_t count,
   _locale_t locale
);
errno_t wcsncpy_s(
   wchar_t *strDest,
   size_t numberOfElements,
   const wchar_t *strSource,
   size_t count
);
errno_t _wcsncpy_s_l(
   wchar_t *strDest,
   size_t numberOfElements,
   const wchar_t *strSource,
   size_t count,
   _locale_t locale
);
errno_t _mbsncpy_s(
   unsigned char *strDest,
   size_t numberOfElements,
   const unsigned char *strSource,
   size_t count
);
errno_t _mbsncpy_s_l(
   unsigned char *strDest,
   size_t numberOfElements,
   const unsigned char *strSource,
   size_t count,
   locale_t locale
);
template <size_t size>
errno_t strncpy_s(
   char (&strDest)[size],
   const char *strSource,
   size_t count
); // C++ only
template <size_t size>
errno_t _strncpy_s_l(
   char (&strDest)[size],
   const char *strSource,
   size_t count,
   _locale_t locale
); // C++ only
template <size_t size>
errno_t wcsncpy_s(
   wchar_t (&strDest)[size],
   const wchar_t *strSource,
   size_t count
); // C++ only
template <size_t size>
errno_t _wcsncpy_s_l(
   wchar_t (&strDest)[size],
   const wchar_t *strSource,
   size_t count,
   _locale_t locale
); // C++ only
template <size_t size>
errno_t _mbsncpy_s(
   unsigned char (&strDest)[size],
   const unsigned char *strSource,
   size_t count
); // C++ only
template <size_t size>
errno_t _mbsncpy_s_l(
   unsigned char (&strDest)[size],
   const unsigned char *strSource,
   size_t count,
   locale_t locale
); // C++ only

参数Parameters

strDeststrDest
目标字符串。Destination string.

numberOfElementsnumberOfElements
目标字符串的大小(以字符为单位)。The size of the destination string, in characters.

strSourcestrSource
源字符串。Source string.

countcount
要复制的字符数或 _TRUNCATENumber of characters to be copied, or _TRUNCATE.

localelocale
要使用的区域设置。The locale to use.

返回值Return Value

如果成功,则为零STRUNCATE如果发生截断,否则错误代码。Zero if successful, STRUNCATE if truncation occurred, otherwise an error code.

错误条件Error Conditions

strDeststrDest numberOfElementsnumberOfElements strSourcestrSource 返回值Return value 内容strDestContents of strDest
NULLNULL 任何any 任何any EINVALEINVAL 未修改not modified
任何any 任何any NULLNULL EINVALEINVAL strDest[0] 设置为 0strDest[0] set to 0
任何any 00 任何any EINVALEINVAL 未修改not modified
NULLnot NULL 过小too small 任何any ERANGEERANGE strDest[0] 设置为 0strDest[0] set to 0

备注Remarks

这些函数尝试将复制第一个D字符strSourcestrDest,其中D较小的计数和长度strSourceThese functions try to copy the first D characters of strSource to strDest, where D is the lesser of count and the length of strSource. 如果这些D字符适合strDest (其大小指定为numberOfElements) 和仍为留出空间 null 终止符,则这些字符所复制并且追加终止 null;否则为strDest[0] 设置 null 字符,并使用无效参数处理程序将调用,如中所述参数验证If those D characters will fit within strDest (whose size is given as numberOfElements) and still leave room for a null terminator, then those characters are copied and a terminating null is appended; otherwise, strDest[0] is set to the null character and the invalid parameter handler is invoked, as described in Parameter Validation.

在上段描述的内容中有一个例外。There is an exception to the above paragraph. 如果计数_TRUNCATE,然后尽可能多的strSource作为可容纳strDest复制同时保留的空间终止始终追加的 null。If count is _TRUNCATE, then as much of strSource as will fit into strDest is copied while still leaving room for the terminating null which is always appended.

例如,应用于对象的For example,

char dst[5];
strncpy_s(dst, 5, "a long string", 5);

我们会要求意味着strncpy_s复制五个字符到缓冲区五个字节长; 因此,这将使为 null 终止符,没有空间strncpy_s将归零,字符串并调用无效参数处理程序。means that we are asking strncpy_s to copy five characters into a buffer five bytes long; this would leave no space for the null terminator, hence strncpy_s zeroes out the string and calls the invalid parameter handler.

如果需要截断行为,使用 _TRUNCATE或 (大小-1):If truncation behavior is needed, use _TRUNCATE or (size - 1):

strncpy_s(dst, 5, "a long string", _TRUNCATE);
strncpy_s(dst, 5, "a long string", 4);

请注意,与不同strncpy,如果计数大于的长度strSource,用最长度的null字符不填充目标字符串计数Note that unlike strncpy, if count is greater than the length of strSource, the destination string is NOT padded with null characters up to length count.

行为strncpy_s是不确定的如果源和目标字符串重叠。The behavior of strncpy_s is undefined if the source and destination strings overlap.

如果strDeststrSourceNULL,或numberOfElements为 0,则调用无效参数处理程序。If strDest or strSource is NULL, or numberOfElements is 0, the invalid parameter handler is invoked. 如果允许执行继续,函数将返回EINVAL和设置errnoEINVALIf execution is allowed to continue, the function returns EINVAL and sets errno to EINVAL.

wcsncpy_s_mbsncpy_s宽字符及多字节字符版本的strncpy_swcsncpy_s and _mbsncpy_s are wide-character and multibyte-character versions of strncpy_s. 参数和返回值的wcsncpy_smbsncpy_s执行相应变化。The arguments and return value of wcsncpy_s and mbsncpy_s do vary accordingly. 否则这六个函数具有相同行为。These six functions behave identically otherwise.

输出值受区域设置的 LC_CTYPE 类别设置影响;有关详细信息,请参阅 setlocaleThe output value is affected by the setting of the LC_CTYPE category setting of the locale; see setlocale for more information. 这些不带 _l 后缀的函数版本使用此区域设置相关的行为的当前区域设置;带有 _l 后缀的版本相同,只不过它们使用传递的区域设置参数。The versions of these functions without the _l suffix use the current locale for this locale-dependent behavior; the versions with the _l suffix are identical except that they use the locale parameter passed in instead. 有关详细信息,请参阅 LocaleFor more information, see Locale.

在 C++ 中,使用这些函数由模板重载简化;重载可以自动推导出缓冲区长度 (不再需要指定大小自变量),并且它们可以自动用以更新、更安全的对应物替换旧的、不安全的函数。In C++, using these functions is simplified by template overloads; the overloads can infer buffer length automatically (eliminating the need to specify a size argument) and they can automatically replace older, non-secure functions with their newer, secure counterparts. 有关详细信息,请参阅 Secure Template OverloadsFor more information, see Secure Template Overloads.

这些函数的调试版本首先用 0xFD 填充缓冲区。The debug versions of these functions first fill the buffer with 0xFD. 若要禁用此行为,请使用 _CrtSetDebugFillThresholdTo disable this behavior, use _CrtSetDebugFillThreshold.

一般文本例程映射Generic-Text Routine Mappings

TCHAR.H 例程TCHAR.H routine 未定义 _UNICODE 和 _MBCS_UNICODE & _MBCS not defined 已定义 _MBCS_MBCS defined 已定义 _UNICODE_UNICODE defined
_tcsncpy_s_tcsncpy_s strncpy_sstrncpy_s _mbsnbcpy_s_mbsnbcpy_s wcsncpy_swcsncpy_s
_tcsncpy_s_l_tcsncpy_s_l _strncpy_s_l_strncpy_s_l _mbsnbcpy_s_l_mbsnbcpy_s_l _wcsncpy_s_l_wcsncpy_s_l

备注

_strncpy_s_l_wcsncpy_s_l_mbsncpy_s_l了任何区域设置依赖项并且只是为了提供 _tcsncpy_s_l并且不应为直接调用。_strncpy_s_l, _wcsncpy_s_l and _mbsncpy_s_l have no locale dependence and are provided just for _tcsncpy_s_l and are not intended to be called directly.

要求Requirements

例程Routine 必需的标头Required header
strncpy_s_strncpy_s_lstrncpy_s, _strncpy_s_l <string.h><string.h>
wcsncpy_s_wcsncpy_s_lwcsncpy_s, _wcsncpy_s_l <string.h> 或 <wchar.h><string.h> or <wchar.h>
_mbsncpy_s_mbsncpy_s_l_mbsncpy_s, _mbsncpy_s_l <mbstring.h><mbstring.h>

有关其他兼容性信息,请参阅 兼容性For additional compatibility information, see Compatibility.

示例Example

// crt_strncpy_s_1.cpp
// compile with: /MTd

// these #defines enable secure template overloads
// (see last part of Examples() below)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>  // For _CrtSetReportMode
#include <errno.h>

// This example uses a 10-byte destination buffer.

errno_t strncpy_s_tester( const char * src,
                          int count )
{
   char dest[10];

   printf( "\n" );

   if ( count == _TRUNCATE )
      printf( "Copying '%s' to %d-byte buffer dest with truncation semantics\n",
               src, _countof(dest) );
   else
      printf( "Copying %d chars of '%s' to %d-byte buffer dest\n",
              count, src, _countof(dest) );

   errno_t err = strncpy_s( dest, _countof(dest), src, count );

   printf( "    new contents of dest: '%s'\n", dest );

   return err;
}

void Examples()
{
   strncpy_s_tester( "howdy", 4 );
   strncpy_s_tester( "howdy", 5 );
   strncpy_s_tester( "howdy", 6 );

   printf( "\nDestination buffer too small:\n" );
   strncpy_s_tester( "Hi there!!", 10 );

   printf( "\nTruncation examples:\n" );

   errno_t err = strncpy_s_tester( "How do you do?", _TRUNCATE );
   printf( "    truncation %s occur\n", err == STRUNCATE ? "did"
                                                       : "did not" );

   err = strncpy_s_tester( "Howdy.", _TRUNCATE );
   printf( "    truncation %s occur\n", err == STRUNCATE ? "did"
                                                       : "did not" );

   printf( "\nSecure template overload example:\n" );

   char dest[10];
   strncpy( dest, "very very very long", 15 );
   // With secure template overloads enabled (see #defines at
   // top of file), the preceding line is replaced by
   //    strncpy_s( dest, _countof(dest), "very very very long", 15 );
   // Instead of causing a buffer overrun, strncpy_s invokes
   // the invalid parameter handler.
   // If secure template overloads were disabled, strncpy would
   // copy 15 characters and overrun the dest buffer.
   printf( "    new contents of dest: '%s'\n", dest );
}

void myInvalidParameterHandler(
   const wchar_t* expression,
   const wchar_t* function,
   const wchar_t* file,
   unsigned int line,
   uintptr_t pReserved)
{
   wprintf(L"Invalid parameter handler invoked: %s\n", expression);
}

int main( void )
{
   _invalid_parameter_handler oldHandler, newHandler;

   newHandler = myInvalidParameterHandler;
   oldHandler = _set_invalid_parameter_handler(newHandler);
   // Disable the message box for assertions.
   _CrtSetReportMode(_CRT_ASSERT, 0);

   Examples();
}
Copying 4 chars of 'howdy' to 10-byte buffer dest
    new contents of dest: 'howd'

Copying 5 chars of 'howdy' to 10-byte buffer dest
    new contents of dest: 'howdy'

Copying 6 chars of 'howdy' to 10-byte buffer dest
    new contents of dest: 'howdy'

Destination buffer too small:

Copying 10 chars of 'Hi there!!' to 10-byte buffer dest
Invalid parameter handler invoked: (L"Buffer is too small" && 0)
    new contents of dest: ''

Truncation examples:

Copying 'How do you do?' to 10-byte buffer dest with truncation semantics
    new contents of dest: 'How do yo'
    truncation did occur

Copying 'Howdy.' to 10-byte buffer dest with truncation semantics
    new contents of dest: 'Howdy.'
    truncation did not occur

Secure template overload example:
Invalid parameter handler invoked: (L"Buffer is too small" && 0)
    new contents of dest: ''

示例Example

// crt_strncpy_s_2.c
// contrasts strncpy and strncpy_s

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
   char a[20] = "test";
   char s[20];

   // simple strncpy usage:

   strcpy_s( s, 20, "dogs like cats" );
   printf( "Original string:\n   '%s'\n", s );

   // Here we can't use strncpy_s since we don't
   // want null termination
   strncpy( s, "mice", 4 );
   printf( "After strncpy (no null-termination):\n   '%s'\n", s );
   strncpy( s+5, "love", 4 );
   printf( "After strncpy into middle of string:\n   '%s'\n", s );

   // If we use strncpy_s, the string is terminated
   strncpy_s( s, _countof(s), "mice", 4 );
   printf( "After strncpy_s (with null-termination):\n   '%s'\n", s );

}
Original string:
   'dogs like cats'
After strncpy (no null-termination):
   'mice like cats'
After strncpy into middle of string:
   'mice love cats'
After strncpy_s (with null-termination):
   'mice'

请参阅See also

字符串操作String Manipulation
区域设置Locale
多字节字符序列的解释Interpretation of Multibyte-Character Sequences
_mbsnbcpy、_mbsnbcpy_l_mbsnbcpy, _mbsnbcpy_l
strcat_s、wcscat_s、_mbscat_sstrcat_s, wcscat_s, _mbscat_s
strcmp、wcscmp、_mbscmpstrcmp, wcscmp, _mbscmp
strcpy_s、wcscpy_s、_mbscpy_sstrcpy_s, wcscpy_s, _mbscpy_s
strncat_s、_strncat_s_l、wcsncat_s、_wcsncat_s_l、_mbsncat_s、_mbsncat_s_lstrncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l
strncmp、wcsncmp、_mbsncmp、_mbsncmp_lstrncmp, wcsncmp, _mbsncmp, _mbsncmp_l
_strnicmp、_wcsnicmp、_mbsnicmp、_strnicmp_l、_wcsnicmp_l、_mbsnicmp_l_strnicmp, _wcsnicmp, _mbsnicmp, _strnicmp_l, _wcsnicmp_l, _mbsnicmp_l
strrchr、wcsrchr、_mbsrchr、_mbsrchr_lstrrchr, wcsrchr, _mbsrchr, _mbsrchr_l
_strset、_strset_l、_wcsset、_wcsset_l、_mbsset、_mbsset_l_strset, _strset_l, _wcsset, _wcsset_l, _mbsset, _mbsset_l
strspn、wcsspn、_mbsspn、_mbsspn_lstrspn, wcsspn, _mbsspn, _mbsspn_l