C語言實現(xiàn)大數(shù)值金額大寫轉(zhuǎn)換的方法詳解
關于大數(shù)值金額大寫轉(zhuǎn)換,在財務管理的應用方面沒什么意義。一般來說,千億級,萬億級的數(shù)值就夠了。因為在國家級層面是以億為單位的,也就表達為千萬億,萬萬億。在企業(yè)層面數(shù)值金額轉(zhuǎn)換設置到千億、萬億就行了。大的集團級企業(yè)擴大到萬萬億也就行了。做企業(yè)應用軟件的可根據(jù)需要設置。至于再大的數(shù)值就是天文數(shù)字,有另外的表達方法。
本人喜歡探索各種算法。前些天寫了15位數(shù)值的金額大寫轉(zhuǎn)換。今再嘗試寫一個更多位數(shù)值的換算大寫轉(zhuǎn)換。提供給需要的同道參考。
金額大寫應用在很多方面,如支票、發(fā)票、各種單據(jù),各種財務憑證,合同文本金額部分。財務方面制定了一套標準的表達法。財務上金額大寫是沒有負數(shù)的,財務上分借方和貸方,負數(shù)就是借方紅字和貸方紅字,也就是赤字。大寫轉(zhuǎn)換的算法要按財務管理的標準來設置。本文詳細介紹算法的要點。
算法的要點
簡單地講就是字串轉(zhuǎn)換處理。若輸入是數(shù)值型則轉(zhuǎn)為字串型。
將輸入的金額分成整數(shù)部分和小數(shù)部分,整數(shù)部分分段為4位數(shù)的萬級段,再按金額數(shù)值逐位轉(zhuǎn)換成中文,拼成大寫字串,然后輸出。
對于不含零的情況,直接就轉(zhuǎn)換好了。然而對于含零和連續(xù)多個零的情況就要消除多余的零。本文介紹的算法就是 ”截數(shù)值位消零法”,或稱 ”截位消零法” 。
要處理的是整數(shù)部分,分四步:
一是 將整數(shù)部分分成整數(shù)的前幾位字段和后面的4位萬級數(shù)字段,
二是 按字段先換成2個字符的數(shù)字和單位的中文表達,
三是 按2個字符截取字段, 將含零的字段消去單位,
四是 處理多余的零,然后拼接整數(shù)和小數(shù),輸出大寫。


轉(zhuǎn)換的算法就一個函數(shù):
Function convert (){ //傳入 snum $ 輸出金額大寫 put$
// M$="零元拾佰仟萬拾佰仟億拾佰仟兆拾佰仟京拾佰仟" ;
M$="零元拾佰仟萬拾佰仟億拾佰仟萬拾佰仟萬拾佰仟" ;
string pn$[50] ;
string dn[8] ; //中國式以每萬為段,4位一段
//對輸入字串截取整數(shù)部分和小數(shù)部分,
//小數(shù)部分直接轉(zhuǎn)換,整數(shù)部分按萬級分段,
//先處理整數(shù)的前幾位,后處理后續(xù)的4位萬級數(shù),
//最后拼接字串輸出金額大寫
//snum="10020005600205" ; //test
g$= subString (snum, 0 ,1 ) ;
//輸入 "0.56" format > " .56"
if(g$=="0") snum= subString (snum,1, 3) ;
nlen=len(snum) ;
n=nlen ;
for (i=0; i<nlen ; i++){
g$= subString (snum, i,1 ) ;
if(g$==".") n= i ; }
if (nlen-n>2) sn$=subString (snum,n+1,2) ;
if (nlen-n==2) sn$=subString (snum,n+1,1)+"0" ;
if (nlen-n==0) sn$="00" ; //無小數(shù)
fn$=subString (snum,0,n) ; //截取整數(shù)部分
print "輸入金額 snum = ", snum ;
// print "整數(shù)部分 fn = ", fn$ ; //test
// print "小數(shù)角分 sn = ", sn$ ;
//開始轉(zhuǎn)換,先處理整數(shù) fn$ ******
chb$="" ; chs$="" ; chsd$="" ;
//角分小數(shù)部分 ******
d1$=subString(sn$,0,1) ;
d2$=subString(sn$,1,1) ;
// print d1$ +" "+d2$ ; //test
if (d1$=="0" ){
c$="零" ; }else{
a$=d1$ ;
snToD ();
c$=c$+"角" ; }
d$ =c$ ;
if (d2$=="0" ){
c$="整" ; }else{
a$=d2$ ;
snToD ();
c$=c$+"分" ; }
d$ =d$+c$ ;
chs$=d$ ; //小數(shù)chs$已轉(zhuǎn)換
// print "chs$ = "+chs$ ; //test
if (d1$=="0"&&d2$=="0" ){ chs$="整" ; }
//開始轉(zhuǎn)換,處理整數(shù) fn$ ******
//4位段整數(shù)轉(zhuǎn)換
nlen=len (fn$) ; //字串長度
n=nlen/4 ; //整數(shù)后4字數(shù)段位數(shù)
k=nlen-nlen/4*4 ; //mod 整數(shù)前幾位
// print "Input fn$ = " + fn$ ; //test
// print "長串前面幾位 k = " , k ;
// print "長串后 4 字段 n = " , n ;
d1$=subString (fn$, 0, k) ;
d2$=subString (fn$, k, nlen) ;
// print "d1$ = " + d1$ ; //test
// print "d2$ = " + d2$ ;
//整數(shù)前幾位轉(zhuǎn)換
for (i=0; i<k ; i++){ //
a$= subString (d1$, i, 1 ) ;
snToD () ; //數(shù)字轉(zhuǎn)大寫 得c$
b$=subString (M$, k - i+n*4,1) ;
p$=subString (N$, n*4+i, 1) ;
chsd$=chsd$+c$+b$ ; } //整數(shù)前幾位
// print "chsd$ = " + chsd$ ; //test
//**** 整數(shù)前幾位完成 chsd$
p$="" ;
for (i=0; i<n ; i++){ //整數(shù)后4數(shù)段位截串
dn[i]= subString (d2$, i*4 , 4 ) ;
p$=p$+ dn[i] +"" ; }
// print "p$ = "+p$ ; //test
int du ; // 4 位數(shù)段
for (du=0; du<n ; du++){ //按整數(shù)4數(shù)段位轉(zhuǎn)換
p$="" ;
for (i=0; i<4 ; i++){ //
a$= subString (dn[du], i, 1 ) ;
snToD () ; //數(shù)字轉(zhuǎn)大寫 得c$
b$=subString (M$, n*4-du*4 - i ,1) ; //單位
p$=p$+c$+b$ ;
pn$[i]=c$+b$ ; } //整數(shù)后4字數(shù)段
chb$=chb$+p$ ; } //du
chb$=chsd$+chb$ ;
// print "chb$ = "+chb$ ; //含零整數(shù)完成test
//***************
p$=" " ;
nlen=len (chb$)/2 ; //按中文二字組字串
// for (i=0; i<30 ; i++){ pn$[i]=" " ; }
for (i=0; i<nlen ; i++){
pn$[i]=subString(chb$, i*2, 2) ; }
//按位數(shù)轉(zhuǎn)換成大寫 format 消單位 **********
p1$="" ; p2$="" ;
p$="" ;
for (k=0; k<nlen ; k++){
p1$=pn$[k] ;
if (p1$=="零仟") { pn$[k]="零" ; }
if (p1$=="零佰") { pn$[k]="零" ; }
if (p1$=="零拾") { pn$[k]="零" ; }
if (p1$=="零元") { pn$[k]="元" ; }
if (p1$=="零萬") { pn$[k]="萬" ; }
if (p1$=="零億") { pn$[k]="億" ; }
} //format
p$="" ;
for (m=0; m<nlen ; m++){ //重組整數(shù)部分>去零
p$=p$+pn$[m] ; }
// print p$ ; //test
nlen= len (p$) ;
for (i=0; i<nlen ; i++){ //renew p$
pn$[i]=subString(p$, i, 1) ; }
for (m=0; m<nlen ; m++){ //去多余 ”零”
p1$=pn$[m] ;
if (p1$=="零"&&pn$[m+1]=="零" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="元" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="萬" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="億" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="兆" ) { pn$[m]="" ; }
}
// print p1$ ; //test
chb$=" " ;
for (i=0; i<nlen ; i++){ //去零后重組整數(shù)部分
chb$=chb$+pn$[i] ; }
//特殊情況100000902 大寫: 壹億萬零玖佰零貳元整
//測試時碰到此例 ”壹億萬零... ” 要消 "萬" ****
//用京兆需要下列代碼,用萬億、萬萬億不需要
nlen= len (chb$) ;
for (i=0; i<nlen ; i++){ //特殊情況,消”萬” ”億”
a$=subString (chb$, i, 1 ) ;
b$=subString (chb$, i+1, 1 ) ;
if (a$=="億"&&b$=="萬") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$= a$+b$ ; }
if (a$=="兆"&&b$=="億") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$=chb$+a$+b$ ; } }
nlen= len (chb$) ;
for (i=0; i<nlen ; i++){ //特殊情況,消”萬”
a$=subString (chb$, i, 1 ) ;
b$=subString (chb$, i+1, 1 ) ;
if (a$=="兆"&&b$=="萬") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$=chb$+a$+b$ ; } }
chb$=chb$+chs$ ; //整數(shù)小數(shù)拼接,完成轉(zhuǎn)換
if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") {
chb$= " 零元整" ; }
//輸出結果 ******
print " 大寫輸出:" ;
put$=chb$ ;
print put$ ; //轉(zhuǎn)換完成輸出
print "...................................." ;
}//convert ()結果圖

完整代碼
//以下是完整的設計測試源碼:
// **** 財務金額大寫顯示 **************
// 本代碼是用簡單的 C 語言寫的,用 MySpringC
// v2.7 編譯調(diào)試通過。可以 VB6, C++, Java 改寫。
// 編譯人:張純叔(micelu@126.com )
//*******************************************
string sBarDes[10];
int nBarId[10];
string snum, put$ ; //傳入金額,輸出大寫
int n, i, j, k, m ;
string N$ , M$, D$ ; //預設置大寫字符
string a$, c$; //轉(zhuǎn)換 傳入a$ 輸出c$
string d$, d1$, d2$ ; //計算小數(shù)角分
string fn$, sn$ ; //整數(shù)字串,小數(shù)字串
string chs$, chb$, chsd$ ; //小寫,大寫,整數(shù)首段
int nlen ; //Len 字數(shù)
string b$, g$, p$, p1$, p2$ ; //計算
main(){
setDisplay (0);
sBarDes[0]="輸入金額";
nBarId[0]=100;
sBarDes[1]=" 測 試 ";
nBarId[1]=101;
sBarDes[2]=" 示 例 ";
nBarId[2]=102;
sBarDes[3]=" ";
nBarId[3]=103;
sBarDes[4]="退出程序 ";
nBarId[4]=104;
setToolBarHeight(10);
setButtonTextSize(15);
setToolBarBackgroundColor(255,220,220,220);
setButtonColor(255,240,240,240);
setButtonTextColor(255,0,0,200);
setToolBar(100,myToolBarProc,sBarDes,nBarId,6);
setTitle("金額大寫轉(zhuǎn)換");
while (){}
}//main ()
convert (){ //傳入 snum $ 輸出金額大寫 put$
// M$="零元拾佰仟萬拾佰仟億拾佰仟兆拾佰仟京拾佰仟" ;
M$="零元拾佰仟萬拾佰仟億拾佰仟萬拾佰仟萬拾佰仟" ;
string pn$[50] ;
string dn[8] ; //中國式以每萬為段,4位一段
//對輸入字串截取整數(shù)部分和小數(shù)部分,
//小數(shù)部分直接轉(zhuǎn)換,整數(shù)部分按萬級分段,
//先處理整數(shù)的前幾位,后處理后續(xù)的4位萬級數(shù),
//最后拼接字串輸出金額大寫
//snum="10020005600205" ; //test
g$= subString (snum, 0 ,1 ) ;
//輸入 "0.56" format > " .56"
if(g$=="0") snum= subString (snum,1, 3) ;
nlen=len(snum) ;
n=nlen ;
for (i=0; i<nlen ; i++){
g$= subString (snum, i,1 ) ;
if(g$==".") n= i ; }
if (nlen-n>2) sn$=subString (snum,n+1,2) ;
if (nlen-n==2) sn$=subString (snum,n+1,1)+"0" ;
if (nlen-n==0) sn$="00" ; //無小數(shù)
fn$=subString (snum,0,n) ; //截取整數(shù)部分
print "輸入金額 snum = ", snum ;
// print "整數(shù)部分 fn = ", fn$ ; //test
// print "小數(shù)角分 sn = ", sn$ ;
//開始轉(zhuǎn)換,先處理整數(shù) fn$ ******
chb$="" ; chs$="" ; chsd$="" ;
//角分小數(shù)部分 ******
d1$=subString(sn$,0,1) ;
d2$=subString(sn$,1,1) ;
// print d1$ +" "+d2$ ; //test
if (d1$=="0" ){
c$="零" ; }else{
a$=d1$ ;
snToD ();
c$=c$+"角" ; }
d$ =c$ ;
if (d2$=="0" ){
c$="整" ; }else{
a$=d2$ ;
snToD ();
c$=c$+"分" ; }
d$ =d$+c$ ;
chs$=d$ ; //小數(shù)chs$已轉(zhuǎn)換
// print "chs$ = "+chs$ ; //test
if (d1$=="0"&&d2$=="0" ){ chs$="整" ; }
//開始轉(zhuǎn)換,處理整數(shù) fn$ ******
//4位段整數(shù)轉(zhuǎn)換
nlen=len (fn$) ; //字串長度
n=nlen/4 ; //整數(shù)后4字數(shù)段位數(shù)
k=nlen-nlen/4*4 ; //mod 整數(shù)前幾位
// print "Input fn$ = " + fn$ ; //test
// print "長串前面幾位 k = " , k ;
// print "長串后 4 字段 n = " , n ;
d1$=subString (fn$, 0, k) ;
d2$=subString (fn$, k, nlen) ;
// print "d1$ = " + d1$ ; //test
// print "d2$ = " + d2$ ;
//整數(shù)前幾位轉(zhuǎn)換
for (i=0; i<k ; i++){ //
a$= subString (d1$, i, 1 ) ;
snToD () ; //數(shù)字轉(zhuǎn)大寫 得c$
b$=subString (M$, k - i+n*4,1) ;
p$=subString (N$, n*4+i, 1) ;
chsd$=chsd$+c$+b$ ; } //整數(shù)前幾位
// print "chsd$ = " + chsd$ ; //test
//**** 整數(shù)前幾位完成 chsd$
p$="" ;
for (i=0; i<n ; i++){ //整數(shù)后4數(shù)段位截串
dn[i]= subString (d2$, i*4 , 4 ) ;
p$=p$+ dn[i] +"" ; }
// print "p$ = "+p$ ; //test
int du ; // 4 位數(shù)段
for (du=0; du<n ; du++){ //按整數(shù)4數(shù)段位轉(zhuǎn)換
p$="" ;
for (i=0; i<4 ; i++){ //
a$= subString (dn[du], i, 1 ) ;
snToD () ; //數(shù)字轉(zhuǎn)大寫 得c$
b$=subString (M$, n*4-du*4 - i ,1) ; //單位
p$=p$+c$+b$ ;
pn$[i]=c$+b$ ; } //整數(shù)后4字數(shù)段
chb$=chb$+p$ ; } //du
chb$=chsd$+chb$ ;
// print "chb$ = "+chb$ ; //含零整數(shù)完成test
//***************
p$=" " ;
nlen=len (chb$)/2 ; //按中文二字組字串
// for (i=0; i<30 ; i++){ pn$[i]=" " ; }
for (i=0; i<nlen ; i++){
pn$[i]=subString(chb$, i*2, 2) ; }
//按位數(shù)轉(zhuǎn)換成大寫 format 消單位 **********
p1$="" ; p2$="" ;
p$="" ;
for (k=0; k<nlen ; k++){
p1$=pn$[k] ;
if (p1$=="零仟") { pn$[k]="零" ; }
if (p1$=="零佰") { pn$[k]="零" ; }
if (p1$=="零拾") { pn$[k]="零" ; }
if (p1$=="零元") { pn$[k]="元" ; }
if (p1$=="零萬") { pn$[k]="萬" ; }
if (p1$=="零億") { pn$[k]="億" ; }
} //format
p$="" ;
for (m=0; m<nlen ; m++){ //重組整數(shù)部分>去零
p$=p$+pn$[m] ; }
// print p$ ; //test
nlen= len (p$) ;
for (i=0; i<nlen ; i++){ //renew p$
pn$[i]=subString(p$, i, 1) ; }
for (m=0; m<nlen ; m++){ //去多余 ”零”
p1$=pn$[m] ;
if (p1$=="零"&&pn$[m+1]=="零" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="元" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="萬" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="億" ) { pn$[m]="" ; }
if (p1$=="零"&&pn$[m+1]=="兆" ) { pn$[m]="" ; }
}
// print p1$ ; //test
chb$=" " ;
for (i=0; i<nlen ; i++){ //去零后重組整數(shù)部分
chb$=chb$+pn$[i] ; }
//特殊情況100000902 大寫: 壹億萬零玖佰零貳元整
//測試時碰到此例 ”壹億萬零... ” 要消 "萬" ****
//用京兆需要下列代碼,用萬億、萬萬億不需要
nlen= len (chb$) ;
for (i=0; i<nlen ; i++){ //特殊情況,消”萬” ”億”
a$=subString (chb$, i, 1 ) ;
b$=subString (chb$, i+1, 1 ) ;
if (a$=="億"&&b$=="萬") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$= a$+b$ ; }
if (a$=="兆"&&b$=="億") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$=chb$+a$+b$ ; } }
nlen= len (chb$) ;
for (i=0; i<nlen ; i++){ //特殊情況,消”萬”
a$=subString (chb$, i, 1 ) ;
b$=subString (chb$, i+1, 1 ) ;
if (a$=="兆"&&b$=="萬") {
a$=subString (chb$, 1, i) ;
b$=subString (chb$, i+2, nlen-i ) ;
chb$=chb$+a$+b$ ; } }
chb$=chb$+chs$ ; //整數(shù)小數(shù)拼接,完成轉(zhuǎn)換
if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") {
chb$= " 零元整" ; }
//輸出結果 ******
print " 大寫輸出:" ;
put$=chb$ ;
print put$ ; //轉(zhuǎn)換完成輸出
print "...................................." ;
}//convert ()結果圖

test (){ //數(shù)值含零空位算法測試
clearOutput ();
print "特殊數(shù)值檢測檢驗:" ;
snum="20000100300000000" ;
convert () ;
snum="100000902" ;
convert () ;
snum="20005600205" ;
convert () ;
snum="3060002065" ;
convert () ;
snum="10508005.75" ;
convert () ;
snum="50700650.5" ;
convert () ;
snum="1802065.06" ;
convert () ;
}//test ()結果圖

sample (){
clearOutput ();
print "輸出示例:" ;
snum="30600702" ;
convert () ;
snum="1500903.08" ;
convert () ;
snum="1020697.00" ;
convert () ;
snum="159533.65" ;
convert () ;
snum="282581697.50" ;
convert () ;
snum="520967.56248" ;
convert () ;
snum="2801697.00" ;
convert () ;
}//sample()
snToD (){ //傳入a$ 返回c$
N$="零壹貳叁肆伍陸柒捌玖" ;
if (a$=="0") c$=subString (N$,0,1) ;
if (a$=="1") c$=subString (N$,1,1) ;
if (a$=="2") c$=subString (N$,2,1) ;
if (a$=="3") c$=subString (N$,3,1) ;
if (a$=="4") c$=subString (N$,4,1) ;
if (a$=="5") c$=subString (N$,5,1) ;
if (a$=="6") c$=subString (N$,6,1) ;
if (a$=="7") c$=subString (N$,7,1) ;
if (a$=="8") c$=subString (N$,8,1) ;
if (a$=="9") c$=subString (N$,9,1) ;
}//snToD ()
input (){//輸入
string m;
snum=stringInput (" 輸入金額轉(zhuǎn)大寫 "," 輸入金額小寫 例: 3572689.36 \n ( 輸出金額大寫 )\n 輸入 [ 空 ] 退出 " ) ;
clearOutput ();
print "Input 金額 = ",snum ;
if (snum=="") { snum=".00" ;
print "輸入為空,請重新輸入。 " ; }
convert () ;
}//input ()
myToolBarProc(int nBtn,int nContext) {
if(nBtn==100){//輸入金額
input (); }
if(nBtn==101){ //test 測試
test () ; }
if(nBtn==102){//示例
sample (); }
if(nBtn==103){//算法測試
// convert () ;
}
if(nBtn==104){//退出程序
clearOutput();
exit (0); }
}//myToolbar ()
//**** End ****到此這篇關于C語言實現(xiàn)大數(shù)值金額大寫轉(zhuǎn)換的方法詳解的文章就介紹到這了,更多相關C語言數(shù)值金額大寫轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
c語言實現(xiàn)數(shù)組循環(huán)左移m位
這篇文章主要介紹了c語言實現(xiàn)數(shù)組循環(huán)左移m位,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07

