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

sprintf 函數詳解:格式化輸出到字串的核心用法與安全陷阱

     編輯:關於C語言

函數原型與基本用法


int sprintf(char* str, const char* format, ...);
  • 將格式化資料寫入字元陣列 str
  • 返回寫入字元數(不含結束符 \0),錯誤返回負值
  • 自動在末尾補 \0

核心功能:任意型別轉字串


char buf[64];
sprintf(buf, "Int: %d, Hex: 0x%X, Float: %.2f, Str: %s", 42, 255, 3.14159, "hello");
// buf = "Int: 42, Hex: 0xFF, Float: 3.14, Str: hello"

格式控制完整語法(同 printf)

%[flags][width][.precision][length]specifier
元素說明範例
flags- (左對齊) + (正負號) 空格 (正數前空格) # (替代形式) 0 (前導零)%-10d, %+d, %#x
width最小欄寬,不足填充%5d → " 42"
.precision小數位數/最大字串長/最小數字位數%.2f, %.5s
lengthhh/h/l/ll/j/z/t/L%hhd, %lld, %Lf
specifierd/i/u/o/x/X/f/F/e/E/g/G/a/A/c/s/p/n%d, %s, %p

安全陷阱:緩衝區溢位

sprintf 不檢查目標緩衝區大小,輸出超過 str 容量會導致緩衝區溢位,嚴重安全漏洞。


// 危險:buf 只有 8 字節,輸出遠超長度
char buf[8];
sprintf(buf, "This is too long"); // 緩衝區溢位!

安全替代方案:snprintf (C99 標準)


int snprintf(char* str, size_t size, const char* format, ...);
  • size:目標緩衝區總大小(含結束符空間)
  • 返回值:本應寫入的字元數(不含 \0),若 ≥ size 發生截斷
  • 永遠保證 str 以 \0 結尾(除非 size==0)

// 安全寫法
char buf[8];
snprintf(buf, sizeof(buf), "Length: %d", 12345);
// buf = "Length: " (截斷),但保證以 \0 結尾,無溢位

進階技巧與常見模式

1. 動態分配足夠空間


// 先用 snprintf 計算所需長度
int len = snprintf(NULL, 0, "User: %s, ID: %d", name, id);
char* buf = malloc(len + 1);
snprintf(buf, len + 1, "User: %s, ID: %d", name, id);

2. 字串拼接(需手動管理偏移)


char buf[256];
int offset = 0;
offset += snprintf(buf + offset, sizeof(buf) - offset, "Part1: %d", a);
offset += snprintf(buf + offset, sizeof(buf) - offset, " Part2: %s", str);

3. 格式化指標地址


void* ptr = &var;
char buf[32];
snprintf(buf, sizeof(buf), "Addr: %p", ptr); // 標準輸出指標格式

4. %n 獲取已寫入字元數


int n;
sprintf(buf, "Prefix%nSuffix", &n); // n = 6 ("Prefix" 長度)

Windows 安全增強版:sprintf_s


int sprintf_s(char* str, size_t size, const char* format, ...); // MSVC 專用
  • 強制要求 size 參數
  • 檢測緩衝區過小、空指標等錯誤並觸發運行時約束處理
  • 非標準,跨平台請用 snprintf

總結:黃金法則

  1. 新代碼一律使用 snprintf,拒絕 sprintf。
  2. 緩衝區大小用 sizeof(buf)(陣列)或變數(動態分配)。
  3. 檢查返回值:>= size 表示發生截斷,需處理。
  4. 格式字串不可來自不可信輸入,防範格式字串漏洞。

掌握 snprintf 安全用法,是 C/C++ 開發者資安素養的基本體現。

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