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

C++ 實現數字轉中文大寫金額 (支付級精度)

     編輯:VC 教學

前言

財務系統、支付模塊、報表打印常需將阿拉伯數字轉為中文大寫金額 (「壹貳參肆伍陸柒捌玖拾佰仟萬億」)。本文提供一個健壯、高效、支持長整型範圍 (萬億級) 的 C++ 實現,核心邏輯為「四位分級、逐級轉換、零值智能處理」。

一、核心數據結構

// 位權單位:個十百千 (級內)
static const char* s_unit1[] = { "拾", "佰", "仟" };
// 級單位:萬、億 (中文按 4 位分級)
static const char* s_unit2[] = { "萬", "億" };
// 數字映射
static const char* s_digital[] = { "零", "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖" };

二、分級處理策略

中文數字讀法按 4 位一級 (個/萬/億) 分組。將長整型拆解為三級:

  • level1:個級 (佰位以下)
  • level2:萬級
  • level3:億級

超過 9999 億 (即萬億) 超出處理範圍,返回失敗。

三、核心算法:GetLevelText (級內轉換)

將 0~9999 數值轉為逆序字符串 (便於後續拼接),智能處理「零」的輸出規則:

  • 連續零只輸出一個「零」。
  • 級末尾的零不輸出 (如 1000 →「壹仟」而非「壹仟零零零」)。
  • 級內部零需輸出 (如 1001 →「壹仟零壹」)。
static void GetLevelText(long level, char* buf) {
    int digit;
    bool bPreZero = false;    // 上一位是否為零
    bool bZeroValidate = false; // 是否已輸出過非零數字 (決定是否輸出前導零)
    int i = 0;                // buf 寫入位置 (按雙字節字符計算)
    int unit = -1;            // 單位索引

    while (level > 0) {
        digit = level % 10;
        if (digit != 0) {
            // 處理前導零:如果前一位是零且已有非零輸出,補一個「零」
            if (bPreZero && bZeroValidate) {
                strcat(buf, s_digital[0]); i += 2;
            }
            // 輸出位權單位 (拾/佰/千)
            if (unit != -1) {
                strcat(buf, s_unit1[unit]); i += 2;
            }
            // 輸出數字
            strcat(buf, s_digital[digit]); i += 2;
            bPreZero = false;
            bZeroValidate = true;
        } else {
            bPreZero = true; // 標記遇到零
        }
        unit++;
        level /= 10;
    }
    buf[i] = '\0'; // 結束符
}

四、主入口:Num2UpDigit (組裝三級)

BOOL Num2UpDigit(long num, char* buf) {
    long level1, level2, level3;
    char level1buf[17] = {0}, level2buf[17] = {0}, level3buf[17] = {0};
    int p = 0; // buf 寫入指針

    // 1. 拆分三級 (從低位向高位)
    level1 = num % 10000;  num /= 10000;
    level2 = num % 10000;  num /= 10000;
    level3 = num;
    if (num / 10000) return FALSE; // 超過 9999 億

    // 2. 逐級轉換 (逆序字符串)
    if (level1) GetLevelText(level1, level1buf);
    if (level2) GetLevelText(level2, level2buf);
    if (level3) GetLevelText(level3, level3buf);

    // 3. 逆序拼接並插入級單位 (萬/億)
    // 處理億級
    if (level3) {
        for (int i = strlen(level3buf) - 2; i >= 0; i -= 2) {
            memcpy(buf + p, level3buf + i, 2); p += 2;
        }
        memcpy(buf + p, s_unit2[1], 2); p += 2; // "億"
    }
    // 處理萬級
    if (level2) {
        // 跨級補零:億級存在且萬級千位為 0 (如 1億0001萬)
        if (level3 && (level2 / 1000 == 0)) {
            memcpy(buf + p, s_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, s_unit2[0], 2); p += 2; // "萬"
    } else if (level3 && level1) { // 億級存在、萬級為 0、個級非 0 → 補「零」
        memcpy(buf + p, s_digital[0], 2); p += 2;
    }
    // 處理個級
    if (level1) {
        // 跨級補零:高級存在且個級千位為 0,且非 (億級存在且萬級為 0) 的特殊情況
        if ((level2 || level3) && (level1 / 1000 == 0) && !(level3 && !level2)) {
            memcpy(buf + p, s_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;
}

五、測試用例與輸出

輸入數值輸出字符串說明
0(空串/需特判)建議調用前特判 0 返回「零元整」
5伍個位
10壹拾十位
101壹佰零壹中間零
1001壹仟零壹連續零只出一個
10000壹萬級單位
10001壹萬零壹跨級補零
100000001壹億零壹萬級為零補零
123456789壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖完整三級

六、工程化建議

  1. 輸入類型擴展:使用 int64_t 或 long long 支持 64 位整數 (9223 萬億),修改分級邏輯為 4 級 (個/萬/億/兆)。
  2. 小數支持:增加角/分處理,將 double 拆分整數/小數部分分別轉換,拼接「元/角/分/整」。
  3. 字符編碼:源文件保存為 UTF-8,或使用 wchar_t/std::wstring 避免多字節字符 memcpy 截斷風險。
  4. 異常處理:負數取絕對值前加「負」,超範圍拋出異常或返回錯誤碼。
  5. 單元測試:覆蓋邊界值 (0, 9, 10, 19, 100, 101, 1000, 1001, 9999, 10000, 10001, 99999999, 99990001 等)。

結語

「四位分級、逆序生成、智能補零」是中文大寫轉換的經典算法模式。本實現代碼緊湊、無外部依賴、易於移植至嵌入式、驅動層或跨平台庫。結合現代 C++ (std::string, string_view, constexpr) 可進一步提升類型安全與性能。

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