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

VC 數字轉人民幣大寫金額算法完整實現:支持整數、小數、零處理與單位遞進

     編輯:關於VC++

核心演算法邏輯

  1. 分離整數部分與小數部分(角、分)
  2. 整數部分按 4 位一組分段(萬、億),段內按千/百/十/個處理
  3. 零處理規則:段內連續零只輸出一個「零」;段末為零不輸出單位;最高段為零不輸出
  4. 小數部分:角、分為零時分別處理「整」字

完整可用代碼


CString NumberToRMB(CString strNumber)
{
    // 1. 預處理:分離整數/小數
    int nDotPos = strNumber.Find(_T('.'));
    CString strInt, strDec;
    if (nDotPos != -1)
    {
        strInt = strNumber.Left(nDotPos);
        strDec = strNumber.Mid(nDotPos + 1);
        if (strDec.GetLength() > 2) strDec = strDec.Left(2); // 保留兩位
        while (strDec.GetLength() < 2) strDec += _T('0');    // 補齊兩位
    }
    else
    {
        strInt = strNumber;
        strDec = _T("00");
    }
    
    // 去除整數部分前導零
    strInt.TrimLeft(_T('0'));
    if (strInt.IsEmpty()) strInt = _T("0");
    
    // 2. 定義常量
    const TCHAR* szDigit  = _T("零壹貳叁肆伍陸柒捌玖");
    const TCHAR* szUnit1  = _T("拾佰仟");           // 段內單位
    const TCHAR* szUnit2  = _T("萬億兆");           // 段單位(每4位)
    
    CString strResult;
    
    // 3. 處理整數部分(從低位向高位,每4位一段)
    int nLen = strInt.GetLength();
    int nSegCount = (nLen + 3) / 4; // 段數
    
    for (int nSeg = 0; nSeg < nSegCount; ++nSeg)
    {
        // 提取當前段 (低位在前)
        int nStart = nLen - (nSeg + 1) * 4;
        if (nStart < 0) nStart = 0;
        int nSegLen = nLen - nSeg * 4 - nStart;
        CString strSeg = strInt.Mid(nStart, nSegLen);
        
        // 段內處理
        CString strSegResult;
        bool bLastZero = false;
        for (int i = 0; i < strSeg.GetLength(); ++i)
        {
            int nDigit = strSeg[i] - _T('0');
            int nPosInSeg = strSeg.GetLength() - 1 - i; // 0=個, 1=十, 2=百, 3=千
            
            if (nDigit == 0)
            {
                if (!bLastZero && i != strSeg.GetLength() - 1) // 非末位零
                    strSegResult += szDigit[0]; // "零"
                bLastZero = true;
            }
            else
            {
                strSegResult += szDigit[nDigit];
                if (nPosInSeg > 0) strSegResult += szUnit1[nPosInSeg - 1];
                bLastZero = false;
            }
        }
        
        // 段結果非空則加段單位
        if (!strSegResult.IsEmpty())
        {
            if (nSeg > 0) strSegResult += szUnit2[nSeg - 1];
            strResult = strSegResult + strResult; // 高段在前
        }
    }
    
    // 4. 處理小數部分(角、分)
    CString strDecResult;
    int nJiao = strDec[0] - _T('0');
    int nFen  = strDec[1] - _T('0');
    
    if (nJiao > 0) strDecResult.Format(_T("%c角"), szDigit[nJiao]);
    if (nFen > 0)  strDecResult.AppendFormat(_T("%c分"), szDigit[nFen]);
    
    // 5. 組合最終結果
    if (strResult.IsEmpty()) strResult = _T("零");
    strResult += _T("元");
    
    if (strDecResult.IsEmpty())
        strResult += _T("整");
    else
        strResult += strDecResult;
    
    return strResult;
}

測試用例對照表

輸入輸出說明
0零元整零值處理
10壹拾元整十位非零
101壹佰零壹元整中間零
1001壹仟零壹元整連續零只一個
10001壹萬零壹元整跨段零
123456789.45壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖元肆角伍分完整大數
100.05壹佰元零伍分角為零
0.10零元壹角整純小數

關鍵細節說明

  • 段內逆序處理:從個位向千位,便於判斷「末位零」不輸出
  • bLastZero 標誌:避免連續輸出多個「零」
  • 段結果前綴拼接:strResult = strSegResult + strResult 實現高段在前
  • 「整」字規則:角分皆為零 → 輸出「整」;角為零分非零 → 輸出「零X分」;角非零分為零 → 輸出「X角整」
  • 擴展性:szUnit2 可續接「京、垓、秭...」支持更大數值

調用示例


void CMyDialog::OnButtonConvert()
{
    UpdateData(TRUE);
    CString strRMB = NumberToRMB(m_strInputNumber);
    m_strOutputRMB = strRMB;
    UpdateData(FALSE);
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved