名稱空間
變體
操作

strcpy, strcpy_s

來自 cppreference.com
< c‎ | string‎ | byte
定義於標頭檔案 <string.h>
(1)
char* strcpy( char* dest, const char* src );
(直到 C99)
char* strcpy( char* restrict dest, const char* restrict src );
(C99 起)
errno_t strcpy_s( char* restrict dest, rsize_t destsz, const char* restrict src );
(2) (C11 起)
1) 複製以 src 所指向的、以空字元結尾的位元組字串(包括空終止符)到其第一個元素由 dest 指向的字元陣列。
如果 dest 陣列不夠大,則行為未定義。如果字串重疊,則行為未定義。如果 dest 不是指向字元陣列的指標,或者 src 不是指向以空字元結尾的位元組字串的指標,則行為未定義。
2)(1) 相同,但它可能會用未指定的值覆蓋目標陣列的其餘部分,並且以下錯誤會在執行時檢測到並呼叫當前安裝的 約束處理函式
  • srcdest 是空指標
  • destsz 為零或大於 RSIZE_MAX
  • destsz 小於或等於 strnlen_s(src, destsz);換句話說,將發生截斷
  • 源字串和目標字串之間會發生重疊
如果 dest 指向的字元陣列的大小 <= strnlen_s(src, destsz) < destsz,則行為未定義;換句話說,destsz 的錯誤值不會暴露即將發生的緩衝區溢位。
與所有邊界檢查函式一樣,只有當實現定義了 __STDC_LIB_EXT1__ 並且使用者在包含 <string.h> 之前將 __STDC_WANT_LIB_EXT1__ 定義為整數常量 1 時,才能保證 strcpy_s 可用。

目錄

[編輯] 引數

dest - 指向要寫入的字元陣列的指標
src - 指向要複製的以空字元結尾的位元組字串的指標
destsz - 要寫入的最大字元數,通常是目標緩衝區的長度

[編輯] 返回值

1) 返回 dest 的副本
2) 成功時返回零,錯誤時返回非零。此外,在錯誤時,將零寫入 dest[0](除非 dest 是空指標或 destsz 為零或大於 RSIZE_MAX)。

[編輯] 注意

允許 strcpy_s 覆蓋目標陣列中從寫入的最後一個字元到 destsz 的部分,以提高效率:它可能以多位元組塊進行復制,然後檢查空位元組。

函式 strcpy_s 類似於 BSD 函式 strlcpy,不同之處在於

  • strlcpy 截斷源字串以適應目標(這是一個安全風險)
  • strlcpy 不執行 strcpy_s 所做的所有執行時檢查
  • 如果呼叫失敗,strlcpy 不會透過將目標設定為 null 字串或呼叫處理程式來使失敗顯而易見。

儘管 strcpy_s 禁止截斷,因為它可能帶來安全風險,但可以使用邊界檢查的 strncpy_s 來截斷字串。

[編輯] 示例

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(void)
{
    const char* src = "Take the test.";
//  src[0] = 'M' ; // this would be undefined behavior
    char dst[strlen(src) + 1]; // +1 to accommodate for the null terminator
    strcpy(dst, src);
    dst[0] = 'M'; // OK
    printf("src = %s\ndst = %s\n", src, dst);
 
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = strcpy_s(dst, sizeof dst, src);
    printf("dst = \"%s\", r = %d\n", dst, r);
    r = strcpy_s(dst, sizeof dst, "Take even more tests.");
    printf("dst = \"%s\", r = %d\n", dst, r);
#endif
}

可能的輸出

src = Take the test.
dst = Make the test.
dst = "Take the test.", r = 0
dst = "", r = 22

[編輯] 參考資料

  • C23 標準 (ISO/IEC 9899:2024)
  • 7.24.2.3 strcpy 函式(p:待定)
  • K.3.7.1.3 strcpy_s 函式(p:待定)
  • C17 標準 (ISO/IEC 9899:2018)
  • 7.24.2.3 strcpy 函式(p:264-265)
  • K.3.7.1.3 strcpy_s 函式(p:447)
  • C11 標準 (ISO/IEC 9899:2011)
  • 7.24.2.3 strcpy 函式(p:363)
  • K.3.7.1.3 strcpy_s 函式(p:615-616)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.21.2.3 strcpy 函式(p:326)
  • C89/C90 標準 (ISO/IEC 9899:1990)
  • 4.11.2.3 strcpy 函式

[編輯] 另請參閱

從一個字串複製一定數量的字元到另一個字串
(函式) [編輯]
將一個緩衝區複製到另一個緩衝區
(函式) [編輯]
(C95)(C11)
將一個寬字串複製到另一個寬字串
(函式) [編輯]
(動態記憶體 TR)
分配字串的副本
(函式) [編輯]
C++ 文件 用於 strcpy