strncpy
, _strncpy_l
, wcsncpy
, _wcsncpy_l
, _mbsncpy
, _mbsncpy_l
將一個字串的字元複製到另一個。 這些函式有更安全的版本可供使用;請參閱 、、 _strncpy_s_l
、 _wcsncpy_s_l
wcsncpy_s
、 _mbsncpy_s
、 _mbsncpy_s_l
。 strncpy_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
大小上的限制。 請參閱下列範例。 如需詳細資訊,請參閱 避免緩衝區滿溢 。
如果 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
如何使用和如何遭誤用,導致程式 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
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應