C標準庫提供多種數值轉字符串函數,按數值類型、標準合規性、格式控制能力各有優劣。本文系統整理整數與浮點數轉換方案,助你選擇最適合的工具。
| 函數 | 原型 | 說明 |
|---|---|---|
itoa | char* itoa(int value, char* str, int base) | 整型轉字符串,base進制(2/8/10/16)。返回str。 |
ltoa | char* ltoa(long value, char* str, int base) | 長整型版。 |
ultoa | char* ultoa(unsigned long value, char* str, int base) | 無符號長整型版。 |
示例:
int num = 100;
char str[25];
itoa(num, str, 10); // str = "100"
printf("num=%d, str=%s\n", num, str);
缺點:非ANSI/ISO C標準,跨平台不可靠(Linux/glibc無此函數)。
sprintf/snprintf(強烈推薦)int num = 100; char str[25]; sprintf(str, "%d", num); // 等價 itoa(num,str,10) snprintf(str, sizeof(str), "%d", num); // 安全版,防溢出 // 進制格式:%d/%i 十進制,%x/%X 十六進制,%o 八進制,%u 無符號十進制 long big = 123456789L; snprintf(str, sizeof(str), "%ld", big);
優勢:標準C(C89)、類型安全(配合格式字符串)、支持寬度/精度/標志(如%08x)、返回寫入字符數便於檢查。
<stdlib.h>,不推薦新代碼)| 函數 | 特點 |
|---|---|
ecvt | 雙精度轉字符串,不含小數點,需單獨返回小數點位置與符號。 |
fcvt | 指定小數位數精度,其餘同ecvt。 |
gcvt | 轉字符串包含小數點,較易用。 |
fcvt示例:
double num = 12345.678; int decpt, sign, ndigits = 3; char *str = fcvt(num, ndigits, &decpt, &sign); // str="12346" (四捨五入), decpt=5 (小數點在第5位後), sign=0 (正數) // 需手動插入小數點:前decpt位為整數部分
缺點:接口複雜、非標準、線程不安全(返回靜態緩衝區)。
sprintf/snprintf(首選)double pi = 3.1415926535; char buf[32]; snprintf(buf, sizeof(buf), "%.5f", pi); // "3.14159" 固定5位小數 snprintf(buf, sizeof(buf), "%e", pi); // "3.141593e+00" 科學記數法 snprintf(buf, sizeof(buf), "%g", pi); // 自動選擇%f或%e,去除尾隨0
格式控制:%.Nf固定N位小數,%.*f動態精度,%a/%A十六進制浮點(C99)。
snprintf配合%.*f動態精度int prec = 6; snprintf(buf, sizeof(buf), "%.*f", prec, pi); // 精度由變量控制
| 函數 | 標準 | 特點 |
|---|---|---|
atoi/atol/atof | C89 | 簡單但無錯誤檢測,錯誤返回0無法區分。 |
strtol/strtoul/strtod | C89 | 推薦:支持進制、指針返回解析結束位置、errno報錯。 |
sscanf | C89 | 格式化掃描,可解析多值,但性能較差。 |
char *end;
long val = strtol("1234", &end, 10); // val=1234, end指向'\0'
double d = strtod("3.14", &end);
snprintf(buf, sizeof(buf), "%d", val)(標準、安全、可控格式)。snprintf(buf, sizeof(buf), "%.Nf", val) 或 %g/%e按需選擇。itoa/fcvt/ecvt/gcvt等非標準函數,除非維護舊代碼且鎖定平台。12字節足夠(INT_MIN含符號11字符+\0),浮點32字節通常足夠,關鍵用snprintf防溢出。掌握snprintf一統江湖,是C語言數值格式化的現代最佳實踐。