C语言实现大数值金额大写转换的方法详解
作者:老花眼猫
关于大数值金额大写转换,在财务管理的应用方面没什么意义。一般来说,千亿级,万亿级的数值就够了。因为在国家级层面是以亿为单位的,也就表达为千万亿,万万亿。在企业层面数值金额转换设置到千亿、万亿就行了。大的集团级企业扩大到万万亿也就行了。做企业应用软件的可根据需要设置。至于再大的数值就是天文数字,有另外的表达方法。
本人喜欢探索各种算法。前些天写了15位数值的金额大写转换。今再尝试写一个更多位数值的换算大写转换。提供给需要的同道参考。
金额大写应用在很多方面,如支票、发票、各种单据,各种财务凭证,合同文本金额部分。财务方面制定了一套标准的表达法。财务上金额大写是没有负数的,财务上分借方和贷方,负数就是借方红字和贷方红字,也就是赤字。大写转换的算法要按财务管理的标准来设置。本文详细介绍算法的要点。
算法的要点
简单地讲就是字串转换处理。若输入是数值型则转为字串型。
将输入的金额分成整数部分和小数部分,整数部分分段为4位数的万级段,再按金额数值逐位转换成中文,拼成大写字串,然后输出。
对于不含零的情况,直接就转换好了。然而对于含零和连续多个零的情况就要消除多余的零。本文介绍的算法就是 ”截数值位消零法”,或称 ”截位消零法” 。
要处理的是整数部分,分四步:
一是 将整数部分分成整数的前几位字段和后面的4位万级数字段,
二是 按字段先换成2个字符的数字和单位的中文表达,
三是 按2个字符截取字段, 将含零的字段消去单位,
四是 处理多余的零,然后拼接整数和小数,输出大写。
转换的算法就一个函数:
Function convert (){ //传入 snum $ 输出金额大写 put$ // M$="零元拾佰仟万拾佰仟亿拾佰仟兆拾佰仟京拾佰仟" ; M$="零元拾佰仟万拾佰仟亿拾佰仟万拾佰仟万拾佰仟" ; string pn$[50] ; string dn[8] ; //中国式以每万为段,4位一段 //对输入字串截取整数部分和小数部分, //小数部分直接转换,整数部分按万级分段, //先处理整数的前几位,后处理后续的4位万级数, //最后拼接字串输出金额大写 //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" ; //无小数 fn$=subString (snum,0,n) ; //截取整数部分 print "输入金额 snum = ", snum ; // print "整数部分 fn = ", fn$ ; //test // print "小数角分 sn = ", sn$ ; //开始转换,先处理整数 fn$ ****** chb$="" ; chs$="" ; chsd$="" ; //角分小数部分 ****** 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$ ; //小数chs$已转换 // print "chs$ = "+chs$ ; //test if (d1$=="0"&&d2$=="0" ){ chs$="整" ; } //开始转换,处理整数 fn$ ****** //4位段整数转换 nlen=len (fn$) ; //字串长度 n=nlen/4 ; //整数后4字数段位数 k=nlen-nlen/4*4 ; //mod 整数前几位 // 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$ ; //整数前几位转换 for (i=0; i<k ; i++){ // a$= subString (d1$, i, 1 ) ; snToD () ; //数字转大写 得c$ b$=subString (M$, k - i+n*4,1) ; p$=subString (N$, n*4+i, 1) ; chsd$=chsd$+c$+b$ ; } //整数前几位 // print "chsd$ = " + chsd$ ; //test //**** 整数前几位完成 chsd$ p$="" ; for (i=0; i<n ; i++){ //整数后4数段位截串 dn[i]= subString (d2$, i*4 , 4 ) ; p$=p$+ dn[i] +"" ; } // print "p$ = "+p$ ; //test int du ; // 4 位数段 for (du=0; du<n ; du++){ //按整数4数段位转换 p$="" ; for (i=0; i<4 ; i++){ // a$= subString (dn[du], i, 1 ) ; snToD () ; //数字转大写 得c$ b$=subString (M$, n*4-du*4 - i ,1) ; //单位 p$=p$+c$+b$ ; pn$[i]=c$+b$ ; } //整数后4字数段 chb$=chb$+p$ ; } //du chb$=chsd$+chb$ ; // print "chb$ = "+chb$ ; //含零整数完成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) ; } //按位数转换成大写 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++){ //重组整数部分>去零 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++){ //去零后重组整数部分 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$ ; //整数小数拼接,完成转换 if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") { chb$= " 零元整" ; } //输出结果 ****** print " 大写输出:" ; put$=chb$ ; print put$ ; //转换完成输出 print "...................................." ; }//convert ()
结果图
完整代码
//以下是完整的设计测试源码: // **** 财务金额大写显示 ************** // 本代码是用简单的 C 语言写的,用 MySpringC // v2.7 编译调试通过。可以 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$; //转换 传入a$ 输出c$ string d$, d1$, d2$ ; //计算小数角分 string fn$, sn$ ; //整数字串,小数字串 string chs$, chb$, chsd$ ; //小写,大写,整数首段 int nlen ; //Len 字数 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("金额大写转换"); while (){} }//main () convert (){ //传入 snum $ 输出金额大写 put$ // M$="零元拾佰仟万拾佰仟亿拾佰仟兆拾佰仟京拾佰仟" ; M$="零元拾佰仟万拾佰仟亿拾佰仟万拾佰仟万拾佰仟" ; string pn$[50] ; string dn[8] ; //中国式以每万为段,4位一段 //对输入字串截取整数部分和小数部分, //小数部分直接转换,整数部分按万级分段, //先处理整数的前几位,后处理后续的4位万级数, //最后拼接字串输出金额大写 //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" ; //无小数 fn$=subString (snum,0,n) ; //截取整数部分 print "输入金额 snum = ", snum ; // print "整数部分 fn = ", fn$ ; //test // print "小数角分 sn = ", sn$ ; //开始转换,先处理整数 fn$ ****** chb$="" ; chs$="" ; chsd$="" ; //角分小数部分 ****** 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$ ; //小数chs$已转换 // print "chs$ = "+chs$ ; //test if (d1$=="0"&&d2$=="0" ){ chs$="整" ; } //开始转换,处理整数 fn$ ****** //4位段整数转换 nlen=len (fn$) ; //字串长度 n=nlen/4 ; //整数后4字数段位数 k=nlen-nlen/4*4 ; //mod 整数前几位 // 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$ ; //整数前几位转换 for (i=0; i<k ; i++){ // a$= subString (d1$, i, 1 ) ; snToD () ; //数字转大写 得c$ b$=subString (M$, k - i+n*4,1) ; p$=subString (N$, n*4+i, 1) ; chsd$=chsd$+c$+b$ ; } //整数前几位 // print "chsd$ = " + chsd$ ; //test //**** 整数前几位完成 chsd$ p$="" ; for (i=0; i<n ; i++){ //整数后4数段位截串 dn[i]= subString (d2$, i*4 , 4 ) ; p$=p$+ dn[i] +"" ; } // print "p$ = "+p$ ; //test int du ; // 4 位数段 for (du=0; du<n ; du++){ //按整数4数段位转换 p$="" ; for (i=0; i<4 ; i++){ // a$= subString (dn[du], i, 1 ) ; snToD () ; //数字转大写 得c$ b$=subString (M$, n*4-du*4 - i ,1) ; //单位 p$=p$+c$+b$ ; pn$[i]=c$+b$ ; } //整数后4字数段 chb$=chb$+p$ ; } //du chb$=chsd$+chb$ ; // print "chb$ = "+chb$ ; //含零整数完成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) ; } //按位数转换成大写 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++){ //重组整数部分>去零 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++){ //去零后重组整数部分 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$ ; //整数小数拼接,完成转换 if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") { chb$= " 零元整" ; } //输出结果 ****** print " 大写输出:" ; put$=chb$ ; print put$ ; //转换完成输出 print "...................................." ; }//convert ()
结果图
test (){ //数值含零空位算法测试 clearOutput (); print "特殊数值检测检验:" ; 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 (" 输入金额转大写 "," 输入金额小写 例: 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语言实现大数值金额大写转换的方法详解的文章就介绍到这了,更多相关C语言数值金额大写转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!