財務系統常需將數字轉為中文大寫(壹貳參肆...),以防竄改。本文提供一個高效、無依賴的 C++ 函數 Num2UpDigit,支援長整數(long)範圍內的完整轉換,正確處理「零」的補位與「萬/億」單位銜接。
level1(個萬)、level2(萬)、level3(億) 三級處理。GetLevelText 處理 0~9999,由低位向高位迴圈,根據數字非零決定是否輸出「零」與單位(拾/佰/仟)。#include
#include
// 單位與數字對照表(雙字元編碼,適用 MBCS/UTF-8 雙位元組中文)
static const char* unit1[] = { "拾", "佰", "仟" };
static const char* unit2[] = { "萬", "億" };
static const char* digital[] = { "零", "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖" };
// 將 0~9999 轉為中文片段(結果存在 buf,低位在前)
static void GetLevelText(long level, char* buf)
{
int digit;
bool bPreZero = false, bZeroValid = false;
int i = 0, unit = -1;
while (level > 0)
{
digit = level % 10;
if (digit != 0)
{
if (bPreZero && bZeroValid)
{
strcat(buf, digital[0]); // 補「零」
i += 2;
}
if (unit != -1)
{
strcat(buf, unit1[unit]); // 輸出拾/佰/仟
i += 2;
}
strcat(buf, digital[digit]); // 輸出壹~玖
i += 2;
bPreZero = false;
bZeroValid = true;
}
else
{
bPreZero = true;
}
unit++;
level /= 10;
}
buf[i] = '\0';
}
// 主轉換函數:num 輸入長整數,buf 輸出緩衝區(建議 64 位元組以上)
// 回傳 TRUE 成功,FALSE 表示超出處理範圍(> 9,999,999,999,999)
BOOL Num2UpDigit(long num, char* buf)
{
long level1, level2, level3;
char level1buf[17] = {0}, level2buf[17] = {0}, level3buf[17] = {0};
int p = 0;
level1 = num % 10000;
num /= 10000;
level2 = num % 10000;
num /= 10000;
level3 = num;
if (num / 10000) return FALSE; // 超過兆單位
if (level1) GetLevelText(level1, level1buf);
if (level2) GetLevelText(level2, level2buf);
if (level3) GetLevelText(level3, level3buf);
// 組裝:從最高級開始反向複製
if (level3)
{
for (int i = strlen(level3buf) - 2; i >= 0; i -= 2)
{
memcpy(buf + p, level3buf + i, 2); p += 2;
}
memcpy(buf + p, unit2[1], 2); p += 2; // 「億」
}
if (level2)
{
if (level3 && level2 / 1000 == 0) { memcpy(buf + p, digital[0], 2); p += 2; }
for (int i = strlen(level2buf) - 2; i >= 0; i -= 2)
{
memcpy(buf + p, level2buf + i, 2); p += 2;
}
memcpy(buf + p, unit2[0], 2); p += 2; // 「萬」
}
else if (level3 && level1) // 億非零、萬為零、個非零 → 補零
{
memcpy(buf + p, digital[0], 2); p += 2;
}
if (level1)
{
if ((level2 || level3) && level1 / 1000 == 0 && !(level3 && !level2))
{
memcpy(buf + p, digital[0], 2); p += 2;
}
for (int i = strlen(level1buf) - 2; i >= 0; i -= 2)
{
memcpy(buf + p, level1buf + i, 2); p += 2;
}
}
buf[p] = '\0';
return TRUE;
}
#include
int main()
{
char buf[64];
long test[] = {0, 5, 10, 105, 1005, 10005, 100005, 1000005, 123456789, 999999999999};
for (long n : test)
{
if (Num2UpDigit(n, buf))
printf("%12ld → %s\n", n, buf);
else
printf("%12ld → 超出範圍\n", n);
}
return 0;
}
0 → 零
5 → 伍
10 → 壹拾
105 → 壹佰零伍
1005 → 壹仟零伍
10005 → 壹萬零伍
100005 → 壹拾萬零伍
1000005 → 壹佰萬零伍
123456789 → 壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖
999999999999 → 玖仟玖佰玖拾玖億玖仟玖佰玖拾玖萬玖仟玖佰玖拾玖
Num2UpDigit 分別處理整數與小數部分,中間插入「元」。char* 改為 wchar_t*,字串常數加 L 前綴,memcpy 改為 wmemcpy。long 改為 long long,並擴充 unit2 加入「兆」、「京」等單位。std::string 或 std::wstring 回傳,避免緩衝區溢位風險。本演算法以「四位一級、級內反向、級間補零」為核心邏輯,代碼精簡且無外部依賴,極適合嵌入財務模組或舊版 VC++ 專案。若專案已使用 C++17/20,建議改寫為 std::wstring ToChineseUpper(long long value) 並搭配 std::format 進一步提升可維護性。