strncpy、_strncpy_l、wcsncpy、_wcsncpy_l、_mbsncpy、_mbsncpy_l

将一个字符串的字符复制给另一个。 提供这些函数的更多安全版本;请参见 strncpy_s、_strncpy_s_l、wcsncpy_s、_wcsncpy_s_l、_mbsncpy_s、_mbsncpy_s_l

重要

_mbsncpy 和 _mbsncpy_l 不能用于在 Windows 运行时. 中执行应用程序。有关更多信息,请参见不支持 /ZW 的 CRT 函数

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 函数将复制 strSource 最初的 count 字符为 strDest 并返回 strDest。 如果 count 小于或等于 strSource的长度,因此 null 字符不会自动附加对复制的字符串。 如果 count 小于长度大于 strSource,目标字符串用空字符。count的长度。 如果源和目标字符串重叠,则 strncpy 的行为未定义。

安全说明安全说明

strncpy 不检查strDest是否有足够空间;因此它是缓冲区溢出的一个可能的原因。限制 count 参数复制的字符数;它不在 strDest的范围的限制。请参见下面的示例。有关更多信息,请参见避免缓冲区溢出

如果 strDest 或 strSource 是一个 NULL 指针, 或 count 小于等于0, the invalid parameter handler is invoked, 将调用无效参数处理程序,如 参数验证中所述。 如果允许执行继续,则这些函数返回 -1 并将 errno 设置为 EINVAL

wcsncpy 和 _mbsncpy 属于 strncpy的宽字符和多字节字符版本。 参数和 wcsncpy 的返回值和 _mbsncpy 相应地改变。 否则这六个函数具有相同行为。

这些带有 _l 后缀的函数的版本相同,只不过它们使用传递区域设置而不是其与区域设置相关的行为的当前区域设置。 有关详细信息,请参阅区域设置

在 C++ 中,这些函数具有模板重载,以调用这些函数的更新、更安全副本。 有关更多信息,请参见安全模板重载

一般文本例程映射

TCHAR.H 例程

未定义的 _UNICODE& 和 _MBCS

已定义 _MBCS

已定义 _UNICODE

_tcsncpy

strncpy

_mbsnbcpy

wcsncpy

_tcsncpy_l

_strncpy_l

_mbsnbcpy_l

_wcsncpy_l

备注

_strncpy_s_l, _strncpy_l 和 _wcsncpy_l 没有区域设置依赖项以及为 _tcsncpy_l 做准备和不打算直接调用。

要求

例程

必需的标头

strncpy

<string.h>

wcsncpy

<string.h> 或 <wchar.h>

_mbsncpy, _mbsncpy_l

<mbstring.h>

有关兼容性的更多信息,请参见兼容性

示例

下面的示例演示如何使用 strncpy,以及如何导致程序 Bug 和安全问题。 编译器为每调用的警告 strncpy 类似于 crt_strncpy_x86.c(15) : warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

// 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.
}

Output

  

自动变量和布局级别错误检测以及受保护代码可以更改编译器的情况随将更改。 此示例可能会有不同的结果,在生成中其他编译环境或使用其他编译器选项。

.NET Framework 等效项

System::String::Copy

请参见

参考

字符串操作 (CRT)

区域设置

多字节字符序列的解释

_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