sprintf 將多型別資料格式化為字串,sscanf 從字串解析提取多型別資料,兩者是 C 語言字串處理的核心利器。本文系統整理格式控制字串語法、進階技巧、常見坑點與最佳實務,附大量實戰範例。
int sprintf(char* buffer, const char* format, ...);
// 返回:寫入字元數(不含結束 \0),失敗返回負值
| 格式 | 說明 | 範例輸出 |
|---|---|---|
%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" |
| 格式 | 說明 | 範例 |
|---|---|---|
%f | 預設 6 位小數 | 3.141593 |
%10.3f | 總寬 10,小數 3 位,右對齊 | " 3.142" |
%-10.3f | 左對齊 | "3.142 " |
%.3f | 不限總寬,小數 3 位 | "3.142" |
| 格式 | 說明 |
|---|---|
%s | 以 \0 結尾的字串 |
%.Ns | 最多取 N 字元(無需 \0 結尾,安全) |
%Ns | 寬度 N,不足左補空格 |
* 佔位符sprintf(s, "%.*s", len, str); // 相當於 "%{len}s"
sprintf(s, "%*.*f", width, prec, val); // 動態寬度與精度
sprintf(s, "%0*d", 8, num); // 動態補 0 寬度
sprintf(s, "%p", &var); // 標準指標格式(含 0x 前綴)
sprintf(s, "%08X", (unsigned)&var); // 手動 32 位十六進位
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,效能顯著提升。
int sscanf(const char* str, const char* format, ...);
// 返回:成功匹配的項目數
%[...] 核心語法| 模式 | 含義 | 範例輸入 → 結果 |
|---|---|---|
%[a-z] | 僅讀取小寫字母 | "abc123" → "abc" |
%[^ ] | 讀取至空格為止 | "hello world" → "hello" |
%[^#] | 讀取至 # 為止 | "abc#def" → "abc" |
%20[^#] | 最多 20 字元,遇 # 停止 | 防緩衝區溢位 |
// 格式:名稱,廠商,型號,數量,價格
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
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", ...
%*d、%*s
// 只取第 1 和第 3 個整數
sscanf("10 20 30", "%d %*d %d", &a, &b); // a=10, b=30
%.Ns 限寬printf 忘寫 buffer* 佔位符尤需注意%f 對應 int 導致堆疊解析錯亂 → 強制轉型 (double)isscanf 返回值未檢查:必須驗證返回值 == 預期項目數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 程式設計師必備的核心技能。