C语言实现大数值金额大写转换的方法详解

 更新时间:2023年03月29日 11:13:01   作者:老花眼猫  
这篇文章主要为大家详细介绍了如何利用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语言数值金额大写转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • OpenGL实现贝塞尔曲线或曲面

    OpenGL实现贝塞尔曲线或曲面

    这篇文章主要为大家详细介绍了OpenGL实现贝塞尔曲线或曲面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • 一篇文章带你了解C++特殊类的设计

    一篇文章带你了解C++特殊类的设计

    这篇文章主要为大家详细介绍了C++特殊类的设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言形参和实参传值和传址详解刨析

    C语言形参和实参传值和传址详解刨析

    形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用,形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送
    2021-11-11
  • C++中拷贝构造函数的应用详解

    C++中拷贝构造函数的应用详解

    这篇文章主要介绍了C++中拷贝构造函数的应用,需要的朋友可以参考下
    2014-07-07
  • C语言中getchar()的原理以及易错点解析

    C语言中getchar()的原理以及易错点解析

    用getchar()函数读取字符串时,字符串会存储在输入缓冲区中,包括输入的回车字符,下面这篇文章主要给大家介绍了关于C语言中getchar()的原理以及易错点解析的相关资料,需要的朋友可以参考下
    2022-03-03
  • c++判断是否为目录的示例分享

    c++判断是否为目录的示例分享

    这篇文章主要介绍了c++判断是否为目录的示例,需要的朋友可以参考下
    2014-03-03
  • 数组和指针的区别深入剖析

    数组和指针的区别深入剖析

    在C/C++中,指针和数组在很多地方可以互换使用,这使得我们产生一种错觉,感觉数组和指针两者是完全等价的,事实上数组和指针是有很大的区别的
    2012-11-11
  • c语言实现数组循环左移m位

    c语言实现数组循环左移m位

    这篇文章主要介绍了c语言实现数组循环左移m位,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C++11系列学习之列表初始化

    C++11系列学习之列表初始化

    这篇文章主要介绍了C++11系列学习之列表初始化,标准初始化方式太过繁杂,限制偏多,因此在新标准中统一了初始化方,为了让初始化具有确定的效果,于是提出了列表初始化概念,下文我们就一起来学习该详细内容介绍吧
    2022-04-04
  • c++将字符串转数字的实例方法

    c++将字符串转数字的实例方法

    在本篇文章里小编给大家整理的是关于c++将字符串转数字的实例方法,有需要的朋友们可以参考下。
    2020-02-02

最新评论