char *strncpy(char *dst, const char *src, size_t count) {
char *tmp = dst;
while (count-- && (*dst++ = *src++) != '\0') ;
return tmp;
}
特性:複製至 \0 或達 count 即停止,不補齊 \0。若 src 長度 ≥ count,dst 不以 \0 結尾,極易造成後續字串操作越界。
char *strncpy(char *dst, const char *src, size_t count) {
char *tmp = dst;
while (count && (*dst++ = *src++) != '\0') count--;
while (count--) *dst++ = '\0';
return tmp;
}
特性:複製 src 至 \0 或達 count;若提前遇 \0,剩餘位元組全部填 \0。保證 dst 前 count 位元組皆被寫入,且若 src 較短則以 \0 尾端填充。
| 情境 | 版本一 | 版本二(標準) |
|---|---|---|
strlen(src) >= count | 複製 count 字元,無 \0 結尾 | 複製 count 字元,無 \0 結尾 |
strlen(src) < count | 複製至 \0 停止,剩餘未寫入 | 複製至 \0,剩餘填 \0 |
dst[count-1] = '\0'。snprintf(dst, count, "%s", src) 或 strlcpy(BSD)等安全替代品。strncpy 不保證字串結尾,strncat 保證。void test(char *p) { p++; } // 只改變區域副本
int main() {
char *a = "123456";
test(a);
puts(a); // 仍輸出 "123456"
a++; puts(a); // 輸出 "23456"
}
指標按值傳遞,函數內修改指標變數本身不影響呼叫端;若需修改呼叫端指標,需傳 char **。