不依賴 stdio.h,從零實現 printf/sprintf 核心格式化邏輯,支援 %d %u %x %X %o %c %s %p %n %%、寬度、精度、標誌(- + 0 # space)、長度修飾符(h l L)。
number()0x)、大小寫。__do_div 宏模擬 64 位除法(內核兼容 32 位架構)。tmp[66],再按格式寫入目標緩衝區。vsprintf()fmt,提取標誌、寬度、精度、長度、類型。va_list 取參,按類型調用 number() 或直接寫字符/字符串。int sprintf(char *buf, const char *fmt, ...) {
va_list args; va_start(args, fmt);
int i = vsprintf(buf, fmt, args);
va_end(args); return i;
}
int printf(const char *fmt, ...) {
char buf[1024];
va_list args; va_start(args, fmt);
int printed = vsprintf(buf, fmt, args);
va_end(args);
puts(buf); // 內核用 console_write,用戶態用 puts/fwrite
return printed;
}
// 標誌位
#define ZEROPAD 1; #define SIGN 2; #define PLUS 4; #define SPACE 8;
#define LEFT 16; #define SMALL 32; #define SPECIAL 64;
// 解析循環
for (str = buf; *fmt; ++fmt) {
if (*fmt != '%') { *str++ = *fmt; continue; }
flags = 0; repeat: ++fmt;
switch (*fmt) { case '-': flags|=LEFT; goto repeat; ... }
// 寬度、精度、* 動態取參
// 長度修飾符 h/l/L
// 類型分發: c/s/p/n/%/o/x/X/d/i/u
// 取參: va_arg(args, type)
// 調用 number() 或直接寫入
}
*str = '\0'; return str - buf;
int main() {
myprintf("輸出字符串:hello world!\n");
myprintf("sum(十進制):%d\n", 7);
myprintf("sum(16進制):%p\n", 7);
char buffer[128];
mysprintf(buffer, "輸出字符串:hello world!\n");
myprintf("buffer:%s\n", buffer);
return 0;
}
輸出:
輸出字符串:hello world!
sum(十進制):7
sum(16進制):0x00000007
輸出字符串:hello world!
buffer:輸出字符串:hello world!
%d %s %x 減小體積)。Linux 內核 vsprintf.c 是 C 語言可變參數格式化輸出的教科書級實現。通過標誌位狀態機解析格式串、統一數字轉換函數 number()、va_list 參數提取,實現了功能完整、可移植、無標準庫依賴的 printf/sprintf 族函數。