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

C 語言 sprintf 與 sscanf 內部機制:數字與字符串雙向轉換的本質

     編輯:關於C語言

sprintf 與 sscanf 是 C 語言格式化輸入輸出的核心,本質上是「數字 ↔ 字符串」的編碼/解碼過程。本文通過內存十六進制分析,揭示其內部執行流程:取模除法分解數字、查碼表轉字符、ASCII 碼存儲、逆向解析累加還原數值。

1. sprintf 將整數轉為字符串


char buf[10];
int i = 1234;
sprintf(buf, "%d", i);
// buf 內存:0x31 0x32 0x33 0x34 0x00 ('1','2','3','4','\0')
// strlen(buf) = 4

內部步驟:

  1. 取模除法分解:1234 → 1, 2, 3, 4(或遞歸除以 10)
  2. 查 ASCII 碼表:數字 n → 字符 '0' + n (即 0x30 + n)
  3. 寫入緩衝區,末尾添加 \0

關鍵點:數值 1234 (0x04D2) 與字符串 "1234" (0x31323334) 內存表示完全不同。

2. sprintf 十六進制格式


int i = 0x1234;
sprintf(buf, "%x", i);
// buf 內存:0x31 0x32 0x33 0x34 ('1','2','3','4')
// 輸出 "1234"

步驟:除 16 取餘 → 十六進制數字 → 查碼表 → 存儲。結果字符串與 %d 1234 相同,但源數值不同(0x1234 vs 1234)。

3. 碼表的雙重作用

  1. 編碼時:數字 → 字符編碼值(如 n + '0')
  2. 顯示時:作業系統/終端根據編碼值渲染字形(ASCII/UTF-8 字形表)

不同編碼(EBCDIC、GBK、UTF-8)下,相同數字轉字符串的二進制表示不同。

4. sscanf 將字符串解析為數字


char buf[5] = "1234"; // 內存 0x31 0x32 0x33 0x34
int i;
sscanf(buf, "%d", &i);
// i = 1234

內部步驟:

  1. 逐字符讀取:'1'(0x31), '2'(0x32), '3'(0x33), '4'(0x34)
  2. 查碼表逆向映射:字符編碼 → 數字值(ch - '0')
  3. 按進制累加:val = val * 10 + digit(十進制)

5. 進制與碼表的綁定關係

  • %d:按 10 進制累加
  • %x:按 16 進制累加
  • %o:按 8 進制累加

相同字符串 "1234",用 %d 解析得 1234,用 %x 解析得 0x1234 (4660)。

6. 類型匹配陷阱


int i = 100;
sprintf(buf, "%.2f", i); // ❌ 錯誤!棧上讀取 8 字節 double,實際只有 4 字節 int
sprintf(buf, "%.2f", (double)i); // ✅ 正確

變參函數無類型檢查,格式串與實際參數類型必須嚴格對應。

總結

sprintf = 數字分解 + 碼表編碼 + 內存存儲;sscanf = 字符讀取 + 碼表解碼 + 進制累加。理解這一本質,有助於調試格式化漏洞、實現自定義序列化、跨平台數據交換。記住:數值內存 ≠ 字符串內存,碼表是橋樑,進制是規則。

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