1、rmb.h
#ifndef rmbH
#define rmbH
// for AnsiString def
// #include
// 數值轉大寫人民幣函數
AnsiString NumToRMBStr(double val);
// 正整數字符串轉漢字函數,不建議單獨使用
// 輸入字符串必須正整數,只允許前導空格(必須右對齊),不宜有前導零
// AnsiString PositiveIntegerToHanStr(const AnsiString &NumStr);
#endif
2、rmb.cpp
#include ??????? // must define AnsiString before rmb.h
#pragma hdrstop???????? // only for C++ Builder
#include
#include "rmb.h"
//---------------------------------------------------------------------------
// 常量字符串定義,如修改也可變為轉換普通漢字函數(如:一二三,十百千)
const char *HanDigiStr[] = {"零","壹","貳","叁","肆","伍","陸","柒","捌","玖"};
const char *HanDiviStr[] = { "","拾","佰","仟","萬","拾","佰","仟","億",
????"拾","佰","仟","萬","拾","佰","仟","億",
????"拾","佰","仟","萬","拾","佰","仟" };
AnsiString PositiveIntegerToHanStr(const AnsiString &NumStr)
{?????// 輸入字符串必須正整數,只允許前導空格(必須右對齊),不宜有前導零
?AnsiString RMBStr;
?int len,n,lastzero=0;
?int hasvalue=0;???// 億、萬進位前有數值標記
?len = NumStr.Length();
?if( len > 24 ) return "數值過大!";
?for(int i=len-1;i>=0;i--) {
??if( NumStr[len-i]==' ' ) continue;????? // AnsiString[] base is 1
??n = NumStr[len-i] - '0';
??if( n<0 || n>9 ) return "輸入含非數字字符!";
??if( n!=0 ) {
???if( lastzero ) RMBStr += HanDigiStr[0];??// 若干零后若跟非零值,只顯示一個零
??????????????????????????????????????????????????????????????????????? // 除了億萬前的零不帶到后面
//???if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) )?? // 如十進位前有零也不發壹音用此行
//???if( !( n==1 && (i%4)==1 && i==len-1 ) )???????? // 十進位處于第一位不發壹音
????RMBStr += HanDigiStr[n];
???RMBStr += HanDiviStr[i];???// 非零值后加進位,個位為空
???hasvalue = 1;?????????????????????????????????? // 置萬進位前有值標記
?? }
??else {
???if( (i%8)==0 || ((i%8)==4 && hasvalue) ) ?// 億萬之間必須有非零值方顯示萬
????RMBStr += HanDiviStr[i];??// "億"或"萬"
?? }
??????????????? if( i%8==0 ) hasvalue = 0;? ???// 萬進位前有值標記逢億復位
??lastzero = (n==0) && (i%4!=0);????????????????? // 億萬前有零后不加零,如:拾萬貳仟
? }
?if( RMBStr.Length()==0 ) return HanDigiStr[0];???????? // 輸入空字符或"0",返回"零"
?return RMBStr;
}
AnsiString NumToRMBStr(double val)
{
?AnsiString SignStr,TailStr;
?double fraction, integer;
?int jiao,fen;
?if( val<0 ) {
??val = -val;
??SignStr = "負";
? }
?fraction = modf(val+0.005, &integer);?????????? // 四舍五入到分
?jiao = int(fraction*10);
?fen = int(fraction*100)-jiao*10;
?if( jiao==0 && fen==0 ) {
??TailStr = "整";
? }
?else {
??TailStr = HanDigiStr[jiao];
??if( jiao!=0 )
???TailStr += "角";
??????????????? if( integer==0 && jiao==0 )???????????? // 零元后不寫零幾分
??????????????????????? TailStr = "";
??if( fen!=0 )
???TailStr += HanDigiStr[fen] + AnsiString("分");
? }
// 下一行可用于非正規金融場合,0.03只顯示"叁分"而不是"零元叁分"
//??????? if( integer==0 ) return? SignStr+TailStr;
?return SignStr+PositiveIntegerToHanStr( AnsiString(integer) )+"元"+TailStr;
}
//-----------------------------------------------------------
// 基本考慮
// 人民幣大寫單位銀行規定用"元"
// 無零頭金額后跟"整",有則不跟
// 角為零時不寫角(如:零叁分)
// 四舍五入到分
// 為減少判讀疑惑(一般對大寫金額預期較高)和
// 體現人民幣基本單位為元,金額低于壹圓前仍加"零元"
// 整數轉換
// 若干零后若跟非零值,只顯示一個零,否則不顯示
// 萬(億)前有零后不加零,因億、萬為一完整單位,
// (如:拾萬貳仟 比 拾萬零貳仟 更順些)
// 億為漢語計數最大單位,只要進位到總是顯示(如:壹億億)
// 萬為次最大單位,億萬之間必須有非零值方顯示萬
// (如"壹億"不可顯示為"壹億萬")
//
// 為減少被竄改的可能性,十進位總發壹音,這和下面的習慣讀法不一樣
//????? (十進位處于第一位不發壹音,如"拾元"非"壹拾元",
//??????? 十進位處前有零是否不發壹音不太確定,
//??????? 如"叁仟零壹拾元"還是"叁仟零拾元"?)
// 用"拾萬"不用"壹拾萬",因為每個整數進位后都有進位單位(拾佰仟萬億)
// 這樣即使金額前沒有附防竄改的前綴如"人民幣"字樣也難竄改些
// 因為至少要加添兩個漢字并且改動后數字必須進位才能竄改成
// (如"拾萬"可改成"叁拾萬",而"壹拾萬"至少要改成"壹佰壹拾萬")
// 此函數為Borland C++ Builder編寫,已充分考慮到跨平臺兼容性
// 如需轉換到其它場合,
// 只需修改字符串類型從AnsiString到對應的類型、功能及函數
// (注意兩個char*型字符串不可以直接相加,需有一個先轉換)
?