成熟穩定的數字轉換為漢字金額大寫文字函數
在開發Grid++Report報表工具的過程中,需要一個將數字轉換為漢字金額大寫文字的函數。在網上也搜索到了一些朋友奉獻的作品,但仔細查閱之后都有一些不足。最后沒有辦法,只好綜合各方的思路再次做了重新發明輪子的事。整個函數還是比較復雜,但有Grid++Report龐大用戶群的考驗,可以保證這個轉換漢字金額大寫的函數是成熟穩定高效的。在此奉獻出來,希望能幫到需要的朋友,免除不必要的做重新發明輪子的苦差。
代碼是用VC++寫的,如下:
#include "stdafx.h"
#include <string>
#include <atlstr.h>
using namespace std;
using namespace ATL;
const char Const_Str_ZeroYuan[] = "零元整";
const char Const_Str_BigAmtNumber[] = "零壹貳叁肆伍陸柒捌玖";
const char Const_Str_HZNegative[] = "負";
const CString strUnit = "元拾佰仟萬拾佰仟億拾佰仟";
const CString strNumber = Const_Str_BigAmtNumber;
const CString strOtherUnit = "整角分";
string ToBigMoney(double dMoney)
{
const double ZeroLowRange = -0.005; //-0.004449;
const double ZeroHighRange = 0.005; //0.004449;
if (ZeroLowRange < dMoney && dMoney < ZeroHighRange)
return Const_Str_ZeroYuan; //"零元整";
bool Negative = FALSE;
if (dMoney <= ZeroLowRange)
{
Negative = TRUE;
dMoney = -dMoney;
}
//這里沒有對超出部份作異常,使用者要注意(現實中不會出現如此巨大的金額數)
CString strMoney;
strMoney.Format ("%.2f" , dMoney);
//將數字分整數部份與小數部份處理
int nPos = strMoney.Find (".");
int nLength = strMoney.GetLength ();
if(nPos < 0)
nPos = nLength;
CString strReturnValue;
int nCount = 0;
bool bZero = false;
bool bNeedLevel = false; //對段的識別,用于是否需要出現段名,如億,萬等
//對整數部份進行反相識別處理
for(int i = nPos - 1;i >= 0;i --)
{
char ch = strMoney.GetAt (i);
if(nCount % 4 == 0 && nCount > 0)
{
//如果處理的數字為第四位(萬),或第八位(億)等,則要求置段
bNeedLevel = true;
}
if(ch == '0')
{
//只對拾佰仟位的0進行識別,主要考慮到拾的特殊性,即如10讀壹拾,不會讀壹拾零
//if(nCount % 4 != 0)
// bZero = true;
bZero = true; //去掉%4判斷, 讓 102000 讀做:壹拾萬零貳仟元整。9,050,155,001-〉玖拾億零伍仟零壹拾伍萬伍仟零壹元整
}
else
{
CString strTemp(strReturnValue);
strReturnValue = strNumber.Mid ((ch - 0x30) * 2 , 2);
if(nCount > 0)
{
strReturnValue += strUnit.Mid (nCount * 2 , 2);
if(nCount % 4 != 0 && bNeedLevel)
{
//這里判斷是否需要讀段名,如萬,億等
strReturnValue += strUnit.Mid (int(nCount / 4) * 8 , 2);
}
bNeedLevel = false;
}
if(bZero)
{
//只有比當前處理的位要低中有數字才補零
if( !strTemp.IsEmpty () )
strReturnValue += strNumber.Left (2);
bZero = false;
}
strReturnValue += strTemp;
}
nCount ++;
}
//如果沒有整數部分,則不用加元
if ( !strReturnValue.IsEmpty() )
strReturnValue += strUnit.Left (2);
//下面實現對小數點后面的處理, 先判斷是否為全零,則不需要繼續讀
bool bAllZero = true;
if(nPos < nLength)
{
if(nLength > 2)
nLength = 2;
for(int i = 0;i < nLength;i ++)
if(strMoney.GetAt (nPos + i + 1) != '0')
bAllZero = false;
}
if(bAllZero)
{
strReturnValue += strOtherUnit.Left (2);
}
else
{
//對角的處理,如果沒有整數部分,則不用加上零角的零
char ch = strMoney.GetAt (nPos + 1);
if(ch != '0' || !strReturnValue.IsEmpty())
strReturnValue += strNumber.Mid ((ch - 0x30) * 2 , 2);
if(ch != '0')
strReturnValue += strOtherUnit.Mid (1 * 2 , 2);
//對分的處理,如果沒有分,角后加‘整’
ch = strMoney.GetAt (nPos + 1 + 1);
if(ch != '0')
{
strReturnValue += strNumber.Mid ((ch - 0x30) * 2 , 2);
strReturnValue += strOtherUnit.Mid (2 * 2 , 2);
}
else
{
strReturnValue += strOtherUnit.Left (2);
}
}
if (Negative)
strReturnValue = Const_Str_HZNegative + strReturnValue;
return string(strReturnValue);
}
銳浪報表Grid++Report源自2003年,經過多年持續不斷發展,是擁有最多軟件開發者的報表工具。易學易用,功能豐富,成熟穩定,支持各種編程環境下的報表開發。
浙公網安備 33010602011771號