名稱空間
變體
操作

strncat, strncat_s

來自 cppreference.com
< c‎ | string‎ | byte
定義於標頭檔案 <string.h>
(1)
char *strncat( char *dest, const char *src, size_t count );
(直到 C99)
char *strncat( char *restrict dest, const char *restrict src, size_t count );
(C99 起)
errno_t strncat_s( char *restrict dest, rsize_t destsz,
                   const char *restrict src, rsize_t count );
(2) (C11 起)
1) 將最多 count 個字元從 src 指向的字元陣列追加到 dest 指向的以空字元結尾的位元組字串的末尾,如果在 src 中遇到空字元則停止。字元 src[0] 替換 dest 末尾的空終止符。終止空字元始終附加在末尾(因此函式最多可以寫入 count+1 個位元組)。
如果目標陣列沒有足夠的空間容納 dest 的內容和 src 的前 count 個字元,以及終止空字元,則行為是未定義的。如果源物件和目標物件重疊,則行為是未定義的。如果 dest 不是指向以空字元結尾的位元組字串的指標,或者 src 不是指向字元陣列的指標,則行為是未定義的。
2)(1) 相同,但此函式可能會破壞目標陣列的其餘部分(從寫入的最後一個位元組到 destsz),並且在執行時檢測到以下錯誤並呼叫當前安裝的約束處理程式函式
  • `src` 或 `dest` 是空指標
  • destszcount 為零或大於 RSIZE_MAX
  • dest 的前 destsz 位元組中沒有空字元
  • 會發生截斷:countsrc 的長度(取較小者)超過了 dest 的空終止符和 destsz 之間可用的空間。
  • 源字串和目標字串之間會發生重疊
如果 dest 指向的字元陣列的大小 < strnlen(dest,destsz)+strnlen(src,count)+1 < destsz,則行為是未定義的;換句話說,destsz 的錯誤值不會暴露即將發生的緩衝區溢位。如果 src 指向的字元陣列的大小 < strnlen(src,count) < destsz,則行為是未定義的;換句話說,count 的錯誤值不會暴露即將發生的緩衝區溢位。
與所有邊界檢查函式一樣,只有當實現定義了 __STDC_LIB_EXT1__ 並且使用者在包含 <string.h> 之前將 __STDC_WANT_LIB_EXT1__ 定義為整數常量 1 時,才能保證 strncat_s 可用。

目錄

[編輯] 引數

dest - 指向要追加的以空字元結尾的位元組字串的指標
src - 指向要複製的字元陣列的指標
count - 要複製的最大字元數
destsz - 目標緩衝區的尺寸

[編輯] 返回值

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

[編輯] 注意

由於 strncat 在每次呼叫時都需要尋找到 dest 的末尾,因此使用 strncat 將許多字串連線成一個字串效率低下。

儘管截斷以適應目標緩衝區是安全風險,因此對於 strncat_s 來說是執行時約束違規,但可以透過將 count 指定為目標陣列大小減一來實現截斷行為:它將複製前 count 個位元組並像往常一樣追加空終止符:strncat_s(dst, sizeof dst, src, (sizeof dst)-strnlen_s(dst, sizeof dst)-1);

[編輯] 示例

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    char str[50] = "Hello ";
    char str2[50] = "World!";
    strcat(str, str2);
    strncat(str, " Goodbye World!", 3);
    puts(str);
 
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    char s1[100] = "good";
    char s5[1000] = "bye";
    int r1 = strncat_s(s1, 100, s5, 1000); // r1 is 0, s1 holds "goodbye\0"
    printf("s1 = %s, r1 = %d\n", s1, r1);
    char s2[6] = "hello";
    int r2 = strncat_s(s2, 6, "", 1); // r2 is 0, s2 holds "hello\0"
    printf("s2 = %s, r2 = %d\n", s2, r2);
    char s3[6] = "hello";
    int r3 = strncat_s(s3, 6, "X", 2); // r3 is non-zero, s3 holds "\0"
    printf("s3 = %s, r3 = %d\n", s3, r3);
    // the strncat_s truncation idiom:
    char s4[7] = "abc";
    int r4 = strncat_s(s4, 7, "defghijklmn", 3); // r4 is 0, s4 holds "abcdef\0"
    printf("s4 = %s, r4 = %d\n", s4, r4);
#endif
}

可能的輸出

Hello World! Go
s1 = goodbye, r1 = 0
s2 = hello, r2 = 0
s3 = , r3 = 22
s4 = abcdef, r4 = 0

[編輯] 參考

  • C23 標準 (ISO/IEC 9899:2024)
  • 7.26.3.2 strncat 函式 (p: 379)
  • K.3.7.2.2 strncat_s 函式 (p: 待定)
  • C17 標準 (ISO/IEC 9899:2018)
  • 7.24.3.2 strncat 函式 (p: 265-266)
  • K.3.7.2.2 strncat_s 函式 (p: 449-450)
  • C11 標準 (ISO/IEC 9899:2011)
  • 7.24.3.2 strncat 函式 (p: 364-365)
  • K.3.7.2.2 strncat_s 函式 (p: 618-620)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.21.3.2 strncat 函式 (p: 327-328)
  • C89/C90 標準 (ISO/IEC 9899:1990)
  • 4.11.3.2 strncat 函式

[編輯] 另請參閱

連線兩個字串
(函式) [編輯]
將一個字串複製到另一個字串
(函式) [編輯]
將一個緩衝區複製到另一個緩衝區,在指定的分隔符處停止
(函式) [編輯]
C++ 文件 關於 strncat