char *strncpy(char *dest, const char *src, size_t n);
#include <string.h>
此為 ISO C 標準函數,廣泛可移植。
從 src 複製最多 n 個字符 到 dest。行為細節:
src 前 n 字符包含結束符 \0:複製至 \0 並停止,dest 剩餘位置填充 \0 直到共 n 字符。src 前 n 字符不含 \0:複製 n 字符,dest 不會自動添加 \0(此時 dest 非合法 C 字符串)。返回 dest 指針。
| 場景 | src 長度 vs n | dest 結果 | 風險 |
|---|---|---|---|
| src 短於 n | len(src) < n | 複製內容 + 尾部填充 \0 | 性能微損(額外填充) |
| src 長於等於 n | len(src) >= n | 僅複製前 n 字符,無 \0 結尾 | 極高:後續當字符串用會越界讀取 |
// strncpy.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char src[] = "Golden Global View";
char dest1[30] = "Hello, GGV Programmers";
char *dest2 = strdup(src); // 副本
// 情況 1: n >= src長度 (含\0) -> 正常複製並填充\0
strncpy(dest1, src, strlen(src)); // 複製整個src(含\0)
printf("1: %s\n", dest1); // Golden Global View
// 情況 2: n < src長度 -> 截斷,無\0結尾!
strncpy(dest2, src, 6); // 複製 "Golden"
// dest2 現在是 "Goldenlobal View" (無\0分隔)
printf("2: %.6s\n", dest2); // 必須用精度限制輸出: Golden
// 安全用法:手動保證\0結尾
char safe_dest[10];
strncpy(safe_dest, src, sizeof(safe_dest) - 1);
safe_dest[sizeof(safe_dest) - 1] = '\0'; // 強制結尾
return 0;
}
snprintf(dest, n, "%s", src):標準 C99,保證 \0 結尾,最推薦。strlcpy (BSD/GNU 擴展):返回 src 長度,保證 \0 結尾,性能優於 snprintf。strncpy(dest, src, n-1); dest[n-1]='\0';。strcpy:複製至 \0,無長度限制(危險)。memcpy:複製指定字節數,不關心 \0,處理二進制數據首選。stpcpy/stpncpy:返回複製後 \0 位置指針(GNU 擴展)。strncpy 設計初衷是處理固定長度字符字段(如舊式 Unix 目錄項、數據庫 CHAR 欄位),而非通用字符串複製。現代代碼中極少直接使用,請優先選擇 snprintf 或封裝後的安全版本,避免「缺失結束符」這一經典漏洞。