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

sprintf 與 sscanf 完全指南:格式化字串構建與解析的瑞士刀

     編輯:關於C

sprintf 將多型別資料格式化為字串,sscanf 從字串解析提取多型別資料,兩者是 C 語言字串處理的核心利器。本文系統整理格式控制字串語法、進階技巧、常見坑點與最佳實務,附大量實戰範例。

一、sprintf 核心語法

int sprintf(char* buffer, const char* format, ...);
// 返回:寫入字元數(不含結束 \0),失敗返回負值

1. 整數格式化

格式說明範例輸出
%d有號十進位sprintf(s, "%d", 123) → "123"
%8d寬度 8,右對齊,左補空格" 123"
%-8d寬度 8,左對齊"123 "
%08d寬度 8,左補 0"00000123"
%x / %X十六進位 小寫/大寫"7b" / "7B"
%08X十六進位大寫,寬度 8 補 0"0000007B"
%o八進位"173"

2. 浮點數格式化

格式說明範例
%f預設 6 位小數3.141593
%10.3f總寬 10,小數 3 位,右對齊" 3.142"
%-10.3f左對齊"3.142 "
%.3f不限總寬,小數 3 位"3.142"

3. 字串格式化

格式說明
%s以 \0 結尾的字串
%.Ns最多取 N 字元(無需 \0 結尾,安全)
%Ns寬度 N,不足左補空格

4. 動態寬度/精度:* 佔位符

sprintf(s, "%.*s", len, str);           // 相當於 "%{len}s"
sprintf(s, "%*.*f", width, prec, val);  // 動態寬度與精度
sprintf(s, "%0*d", 8, num);             // 動態補 0 寬度

5. 指標/位址列印

sprintf(s, "%p", &var);      // 標準指標格式(含 0x 前綴)
sprintf(s, "%08X", (unsigned)&var); // 手動 32 位十六進位

6. 利用返回值高效拼接


char buf[256];
int offset = 0;
for (int i = 0; i < 10; ++i) {
    offset += sprintf(buf + offset, "%d,", rand() % 100);
}
buf[offset - 1] = '\n'; // 替換最後逗號

避免 strcat 每次掃描尾端 \0,效能顯著提升。

二、sscanf 解析進階

int sscanf(const char* str, const char* format, ...);
// 返回:成功匹配的項目數

1. 掃描集 %[...] 核心語法

模式含義範例輸入 → 結果
%[a-z]僅讀取小寫字母"abc123" → "abc"
%[^ ]讀取至空格為止"hello world" → "hello"
%[^#]讀取至 # 為止"abc#def" → "abc"
%20[^#]最多 20 字元,遇 # 停止防緩衝區溢位

2. 實戰:CSV 風格欄位解析


// 格式:名稱,廠商,型號,數量,價格
char line[] = "Notebook,IBM,ThinkPad X32,6,12000";
char name[21], vendor[21], model[21];
int qty; float price;

sscanf(line, "%20[^,],%20[^,],%20[^,],%d,%f",
       name, vendor, model, &qty, &price);
// name="Notebook", vendor="IBM", model="ThinkPad X32", qty=6, price=12000

3. 複雜日誌行解析


char log[] = "<14>2002-11-11 12:12:12 11.22.33.44 3 3 aaaa aaaaaa";
int level, a5, a6;
char date[20], time[20], ip[20], str7[20];

sscanf(log, "<%d>%s %s %s %d %d %s",
       &level, date, time, ip, &a5, &a6, str7);
// level=14, date="2002-11-11", time="12:12:12", ip="11.22.33.44", ...

4. 跳過欄位:%*d、%*s


// 只取第 1 和第 3 個整數
sscanf("10 20 30", "%d %*d %d", &a, &b); // a=10, b=30

三、常見坑點與防範

  1. 緩衝區溢位:目標緩衝區過小 → 分配足夠空間,字串用 %.Ns 限寬
  2. 遺漏第一參數:習慣 printf 忘寫 buffer
  3. 參數對位錯誤:格式符與實參數量/型別不符 → 嚴格對照,* 佔位符尤需注意
  4. 型別不匹配:%f 對應 int 導致堆疊解析錯亂 → 強制轉型 (double)i
  5. sscanf 返回值未檢查:必須驗證返回值 == 預期項目數

四、姊妹函數:strftime 時間格式化


time_t t = time(NULL);
char s[32];
strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));
// "2024-01-15 14:30:45"

MFC 對應:CString::Format / CTime::Format,型別安全更優雅。

掌握 sprintf/sscanf 的格式控制微語言,能以極簡代碼解決複雜字串構建與解析問題,是 C 程式設計師必備的核心技能。

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