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

snprintf 安全格式化字串函數完整用法指南與測試實測

     編輯:更多程式設計知識

函數原型

int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
  • 最多寫入 n-1 字元,結尾自動補 \0,緩衝區大小為 n 時不會溢位。
  • 回傳值:欲寫入的總字元數 (不含結尾 \0),若發生錯誤回傳負值。
  • 關鍵:回傳值可能大於等於 n,表示被截斷。

推薦用法:傳入 sizeof(buf)

char str[10] = {0};
snprintf(str, sizeof(str), "0123456789012345678");
printf("str=%s\n", str); // 輸出: 012345678 (9字元 + \0)

不推薦:手動指定長度大於緩衝區

char str[10] = {0};
snprintf(str, 18, "0123456789012345678"); // n=18 > sizeof(str)=10
printf("str=%s\n", str); // 未定義行為!可能緩衝區溢位

回傳值實測

char str1[10] = {0}, str2[10] = {0};
int ret1 = snprintf(str1, sizeof(str1), "%s", "abc");       // 完整寫入
int ret2 = snprintf(str2, 4, "%s", "aaabbbccc");            // 截斷
printf("ret1=%d, str1=%s\n", ret1, str1); // ret1=3, str1=abc
printf("ret2=%d, str2=%s\n", ret2, str2); // ret2=9, str2=aaa
  • ret1=3:實際寫入 3 字元,等於欲寫入長度。
  • ret2=9:欲寫入 9 字元 (aaabbbccc),但緩衝區僅 4 位元組 (含 \0),實際寫入 aaa\0,回傳 9 提示被截斷。

格式化字串長度計算

char dst[10] = {0};
char src1[] = "aaa";
char src2[] = "aaabbbcccddd";
int ret1 = snprintf(dst, sizeof(dst), "str:%s", src1); // "str:aaa" (7字元) OK
int ret2 = snprintf(dst, sizeof(dst), "str:%s", src2); // 欲寫 15 字元,截斷為 "str:aa"
printf("ret1=%d, ret2=%d\n", ret1, ret2); // 7, 15

常見錯誤與修正

錯誤寫法問題修正
snprintf(buf, len, fmt, ...); // len 為字串長度而非緩衝區大小若 len > sizeof(buf) 導致溢位snprintf(buf, sizeof(buf), fmt, ...);
忽略回傳值無法偵測截斷檢查 ret >= sizeof(buf) 判斷是否截斷
重疊緩衝區未定義行為確保 src 與 dst 不重疊

總結

snprintf 是 C/C++ 格式化字串的安全基石。核心原則:**永遠傳入 `sizeof(buffer)` 作為 `n`**,並**檢查回傳值是否 ≥ `sizeof(buffer)`** 以偵測截斷。嚴禁手動指定超過緩衝區大小的 `n`。

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