strncpy, _strncpy_l, wcsncpy, _wcsncpy_l, _mbsncpy, _mbsncpy_l

將一個字串的字元複製到另一個。 這些函式有更安全的版本可供使用;請參閱 、、 _strncpy_s_l_wcsncpy_s_lwcsncpy_s_mbsncpy_s_mbsncpy_s_lstrncpy_s

重要

在 Windows 執行階段中執行的應用程式中無法使用 _mbsncpy_mbsncpy_l。 如需詳細資訊,請參閱 CRT functions not supported in Universal Windows Platform apps (通用 Windows 平台應用程式中不支援的 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 的長度,則會以 null 字元填補目的字串,直到長度達 count 為止。 如果來源和目的字串重疊,則 strncpy 的行為未定義。

重要

strncpy 不會檢查在 strDest 中是否有足夠的空間;使得這成為緩衝區滿溢的潛在原因。 count 引數會限制複製的字元數目;這並非 strDest 大小上的限制。 請參閱下列範例。 如需詳細資訊,請參閱 避免緩衝區滿溢

如果 strDeststrSourceNULL 指標,或如果 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 如何使用和如何遭誤用,導致程式 Bug 和安全性問題。 編譯器會為每個呼叫 strncpy 產生類似 crt_strncpy_x86.c(15) 的警告:warning 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