首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 標準庫函數詳解:strncpy — 指定長度字符串複製

     編輯:關於C語言

函數原型

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 ndest 結果風險
src 短於 nlen(src) < n複製內容 + 尾部填充 \0性能微損(額外填充)
src 長於等於 nlen(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;
}

安全替代方案

  1. snprintf(dest, n, "%s", src):標準 C99,保證 \0 結尾,最推薦。
  2. strlcpy (BSD/GNU 擴展):返回 src 長度,保證 \0 結尾,性能優於 snprintf。
  3. 手動封裝:strncpy(dest, src, n-1); dest[n-1]='\0';。

相關函數

  • strcpy:複製至 \0,無長度限制(危險)。
  • memcpy:複製指定字節數,不關心 \0,處理二進制數據首選。
  • stpcpy/stpncpy:返回複製後 \0 位置指針(GNU 擴展)。

總結

strncpy 設計初衷是處理固定長度字符字段(如舊式 Unix 目錄項、數據庫 CHAR 欄位),而非通用字符串複製。現代代碼中極少直接使用,請優先選擇 snprintf 或封裝後的安全版本,避免「缺失結束符」這一經典漏洞。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved