免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 12877 | 回复: 24
打印 上一主题 下一主题

求小写的金额转成大写金额的程式~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-02 14:28 |只看该作者 |倒序浏览
请高手给发一个把   小写的金额转成大写金额的程式,非常感谢

如:小写金额为 8888.88
转化为  大写 捌仟捌百捌十捌点捌捌元

谢谢大侠~

论坛徽章:
0
2 [报告]
发表于 2007-01-02 15:14 |只看该作者
参考以下帖子应该可以得到启发:
http://bbs.chinaunix.net/viewthr ... p;extra=&page=1

论坛徽章:
0
3 [报告]
发表于 2007-01-02 15:21 |只看该作者
(转)小写金额转换为大写金额(C实现)

  大多的算法都是直接分析字符串生成大写金额,即存在一个假设:源字符串的格式是正确的。在我的过程中,用状态机的方法分析源字符串,错误时,返回空指针(我可不敢保证传给我的过程的都是##.##)。 分析出源字符串中整数部有多少个数字,是否有小数,统计结果放在一个结构体中,整数和小数部分的数字分别放在两个整形数组里。

  有了统计数据就可以生成大写金额了。转换过程有个难点:要区分万、亿等“段”,特别是个位这个“段”,这个概念是在《小写转大写金额在C++中的实现》文章中提到的。在下面的程序中用j=(size-i-1)&0x3,实际上是j=(size-i-1)%4取模,j==0时为段尾,需要特殊处理。所有的处理都是围绕0来进行的,也就是说,0才是难点。

  特殊位置的0,按段分,段中第一个非0数字前的0,可能有多个;段中两个非0数字间的0;段尾的0;个位的0;十分位,角位置的0。

  另外,转换的一个重点是大写金额的写法,好像大多的算法都注重转换过程而对这个问题没有深究。我在文章后面附上转换规则。

  有一点,从低耦合的角度说,这个过程应该再细分一下。输入可以是标准格式的字符串或数字,验证的过程可以放到另一个模块中。我就不再分了,总体上,while语句整体是格式分析过程,可以单独拿出来。后面的代码是生成大写读法。需要的自己处理下吧,很简单。

下面是代码

  1. /**
  2. * @brief 将源字符串中的小写金额转换为大写格式
  3. *
  4. * @param dest 目的字符串
  5. * @param src  小写金额字符串
  6. * @return
  7. * - NULL 源字符串的格式错误,返回NULL
  8. * - 非NULL 目的字符串的首地址
  9. * @note 转换根据:中国人民银行会计司编写的最新《企业、银行正确办理支付结算
  10. *       指南》的第114页-第115页
  11. */
  12. char* chineseFee( char* dest, char* src )
  13. {
  14.     enum
  15.     {
  16.         START,                 //开始
  17.         MINUS,                 //负号
  18.         ZEROINT,               //0整数
  19.         INTEGER,               //整数
  20.         DECIMAL,               //小数点
  21.         DECIMALfRACTION,       //小数位
  22.         END,                   //结束
  23.         ERROR                  //错误
  24.     } status = START;

  25.     struct
  26.     {
  27.         int minus;             //0为正,1为负
  28.         int sizeInt;
  29.         int sizeDecimal;
  30.         int integer[10];
  31.         int decimal[10];
  32.     } feeInfo;

  33.     char* NumberChar[] =
  34.         { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
  35.     char* UnitChar[] =
  36.         { "整", "圆", "拾", "佰","仟", "万", "拾", "佰", "仟", "亿",
  37.           "拾", "佰", "仟", "万亿", "拾", "佰", "仟", "亿亿",
  38.           "角", "分", "负", "人民币" };
  39.          
  40.     int      i, j,size;             //循环变量
  41.     int      zeroTag        = 0,    //0标志
  42.              decZeroTag     = 0;
  43.       
  44.     char*    pDest          = dest;
  45.     char*    pSrc           = src;
  46.    
  47.     int*     pInt           = feeInfo.integer;
  48.     int*     pDec           = feeInfo.decimal;
  49.    
  50.     //初始化
  51.     feeInfo.sizeInt        = 0;
  52.     feeInfo.sizeDecimal    = 0;
  53.     feeInfo.minus          = 0;
  54.    
  55.     //分析字符串
  56.     while( 1 )
  57.     {
  58.         switch ( *pSrc )
  59.         {
  60.             case '-' :
  61.                 status = ( status == START ) ? MINUS : ERROR;
  62.                 feeInfo.minus = ( status == MINUS ) ? 1 : 0;
  63.                 break;
  64.             case '1' :
  65.             case '2' :
  66.             case '3' :
  67.             case '4' :
  68.             case '5' :
  69.             case '6' :
  70.             case '7' :
  71.             case '8' :
  72.             case '9' :
  73.             case '0' :
  74.                 if ( *pSrc == '0' && status == ZEROINT )//|| status == START ) )
  75.                 {
  76.                     status = ERROR;
  77.                     break;
  78.                 }
  79.                 if ( status == MINUS || status == START || status == INTEGER )
  80.                 {
  81.                     if ( *pSrc == '0' && ( status == MINUS || status == START ) )
  82.                         status = ZEROINT;
  83.                     else
  84.                         status = INTEGER;
  85.                     *pInt = (*pSrc) - 48;
  86.                     ++pInt;
  87.                     ++feeInfo.sizeInt;
  88.                 }
  89.                 else if ( status == DECIMAL || status == DECIMALfRACTION )
  90.                 {
  91.                     status = DECIMALfRACTION;
  92.                     *pDec = (*pSrc) - 48;
  93.                     ++pDec;
  94.                     ++feeInfo.sizeDecimal;
  95.                 }
  96.                 else
  97.                 {
  98.                     status =ERROR;
  99.                 }
  100.                 break;
  101.             case '.' :
  102.                 status = ( status == INTEGER || status == ZEROINT )
  103.                          ? DECIMAL : ERROR;
  104.                 break;
  105.             case '' :
  106.                 status = ( status == INTEGER || status == DECIMALfRACTION
  107.                            || status == ZEROINT ) ? END : ERROR;
  108.                 break;
  109.             default :
  110.                 status = ERROR;
  111.         }
  112.         if ( status == END )
  113.             break;
  114.         else if ( status == ERROR )
  115.             return NULL;
  116.         
  117.         ++pSrc;
  118.     }
  119.    
  120.     //只有1位小数时,设置百分位为0,使下面代码不需要区分这两种情况
  121.     if ( feeInfo.sizeDecimal == 1 )
  122.     {
  123.         feeInfo.decimal[ 1 ] = 0;
  124.         ++feeInfo.sizeDecimal;
  125.     }

  126.     //判断是否需要打印小数部分,有小数部且十分位和百分位不都为0
  127.     //需要打印小数部时,zeroTag设为0,否则设为1
  128.     if ( feeInfo.sizeDecimal == 0                                 //没有小数
  129.         || ( !feeInfo.decimal[ 0 ] && !feeInfo.decimal[ 1 ] ) )   //小数部都为0
  130.         decZeroTag = 1;
  131.     else
  132.         decZeroTag = 0;
  133.         
  134.     //printf( "int size: %d    decimal size: %d ", feeInfo.sizeInt, feeInfo.sizeDecimal );
  135.    
  136.     strcpy( pDest, UnitChar[ 21 ] );                  //初始化目标字符串-人民币
  137.    
  138.     if ( feeInfo.minus ) strcat( pDest, UnitChar[ 20 ] );    //负号
  139.         
  140.     //处理整数部分
  141.     size = feeInfo.sizeInt;
  142.     for( i = 0; i < size; ++i )
  143.     {
  144.         j = size - i - 1 & 0x3;                              //j = 0时为段尾
  145.         if ( feeInfo.integer[ i ] == 0 && j )                //处理非段尾0
  146.         {
  147.             zeroTag = 1;
  148.         }
  149.         else if ( feeInfo.integer[ i ] == 0 && !j )          //处理段尾0
  150.         {
  151.             if ( feeInfo.sizeInt == 1 && decZeroTag )        //特殊处理个位0
  152.                 strcat( pDest, NumberChar[ feeInfo.integer[ i ] ] );
  153.             if ( feeInfo.sizeInt != 1 || decZeroTag )
  154.                 strcat( pDest, UnitChar[ size - i ] );
  155.             zeroTag = 0;
  156.         }
  157.         else                                                 //处理非0
  158.         {
  159.             if ( zeroTag )
  160.             {
  161.                 strcat( pDest, NumberChar[ 0 ] );
  162.                 zeroTag = 0;
  163.             }
  164.             strcat( pDest, NumberChar[ feeInfo.integer[ i ] ] );
  165.             strcat( pDest, UnitChar[ size - i ] );
  166.             if ( !j ) zeroTag = 0;                      //如果是段尾,设为非标志
  167.         }
  168.     }
  169.    
  170.     if ( decZeroTag )
  171.     {
  172.         strcat( pDest, UnitChar[ 0 ] );//没有小数部,打印"整"字符
  173.     }
  174.     else
  175.     {
  176.         //十分位
  177.         if ( feeInfo.decimal[ 0 ] )
  178.         {
  179.             strcat( pDest, NumberChar[ feeInfo.decimal[ 0 ] ] );
  180.             strcat( pDest, UnitChar[ 18 ] );
  181.         }
  182.         else if ( feeInfo.sizeInt != 1 || feeInfo.integer[ 0 ] )
  183.         {
  184.             strcat( pDest, NumberChar[ feeInfo.decimal[ 0 ] ] );
  185.         }
  186.         
  187.         //百分位不为0时
  188.         if ( feeInfo.decimal[ 1 ] )   
  189.         {
  190.             strcat( pDest, NumberChar[ feeInfo.decimal[ 1 ] ] );
  191.             strcat( pDest, UnitChar[ 19 ] );
  192.         }
  193.     }
  194.     return dest;
  195. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2007-01-02 16:44 |只看该作者
这应该不是什么难题吧.

rpg实现起来,也应该不是什么问题,就是麻烦。

简单说下方法,仅供参考:
1,做个tab,值是0~9的大写,写程序的时候,对于金额的每一位,你都要到tab里面去做
检索,检索到后,将tab里面的值取出。
2,然后就是区分万,千,百位的问题了。可不可以这么考虑,你先找出小数点的位子,然后
确定小数点前面的个数,然后,百,千,万这些单位就好确定了吧。
3,剩下的任务就应该是把每一个字符连接起来,做成字符串,这样应该就可以了。

说的比较泛泛,但是我觉得如果是rpg程序,这样肯定可以实现。
有个命令,不知道你知道不,chckr查询字符串的,用这个命令,可能简单些。

论坛徽章:
0
5 [报告]
发表于 2007-01-02 17:03 |只看该作者
谢谢轻舟老大和楼上的那位兄弟,谢谢,刚刚接触400,所以技术很菜


我程式有自己写出一点点出来, 编译也错了,但是就是显示不出大写拉,执行之后出现的是乱码,我也不知道是哪里搞错了,请朋友们帮我看一下,请轻舟老大和楼上的兄弟帮帮忙,谢谢你们了.程式如下:
                                 
 H                                                  1         
 FSF02F   IF  E           K        DISK                       
  FSF02FP  IF  E           K        DISK                      A
 E                    TAB01   1  10  1 0 TAB02  13            
 I*RSF02F                                                     
 I*             SUDPT                           SUDPTA        
 I            DS                                             
 I                                        1  132SUDPT         
 I                                        1   10SUDP1         
 I                                        2   20SUDP2         
 I                                        3   30SUDP3         
 I                                        4   40SUDP4         
 I                                        5   50SUDP5         
 I                                        6   60SUDP6         
 I                                        7   70SUDP7      
 I                                        8   80SUDP8
 I                                        9   90SUDP9
 I                                       10  100SUDP10
 I                                       11  110SUDP11
 I                                       12  120SUDP12
 I                                       13  130SUDP13
 I            DS                                      
 I                                        1  13 FZKK  
 I                                        1   1 FZK1  
 I                                        2   2 FZK2   
 I                                        3   3 FZK3   
 I                                        4   4 FZK4   
 I                                        5   5 FZK5   
 I                                        6   6 FZK6   
 I                                        7   7 FZK7   
 I                                        8   8 FZK8   
 I                                        9   9 FZK9   
 I                                       10  10 FZK10  
 I                                       11  11 FZK11  
 I                                       12  12 FZK12  
 I                                       13  13 FZK13  
 C                     MOVE *BLANK    FZKK   13        
 C           *LOVAL    SETLLSF02F                40   
 C           *IN40     DOWEQ'0'                        
 C                     READ SF02F                    40
 C           *IN40     IFEQ '0'                        
 C           SIVNO     CHAINRSF02FP              88   
 C           SUDP1     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK1              
 C           SUDP2     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK2              
 C           SUDP3     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK3              
 C           SUDP4     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK4              
 C           SUDP5     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK5            
 C           SUDP6     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK6            
 C           SUDP7     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK7            
 C           SUDP8     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK8            
 C           SUDP9     LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK9            
 C           SUDP10    LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK10            
 C           SUDP11    LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK11            
 C           SUDP12    LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK12            
 C           SUDP13    LOKUPTAB01     TAB02          91
 C   91                MOVE TAB02     FZK13            
 C                     MOVELSIVNO     SIVNN            
 C                     MOVELFZKK      FZK              
 C   88                WRITERSF02FP                    
 C                     ENDIF                           
 C                     ENDDO                           
 C                     SETON                     LR   
**   
**   
0 零
1 壹
2 贰
3 叁
4 肆
5 伍
6 陆
7 柒
8 捌
9 玖

论坛徽章:
0
6 [报告]
发表于 2007-01-03 08:53 |只看该作者
你可以做个关联表试一试

0001.00      E                    TAB1    1   9  1   TAB2    2                               061230  
0002.00      C                     MOVEL'B'       AA      1                                  061219  
0003.00      C                     MOVEL*BLANK    BB      1                                  061219  
0004.00      C                     Z-ADD1         X       20                                 061219  
0005.00      C           AA        LOKUPTAB1      TAB2           90                          061230  
0012.00      C   90      TAB2      DSPLY                                                     061230  
0015.00      C                     SETON                     LR                              061214  
0016.00      C                     RETRN                                                     061214  
0017.00 ** TAB1 TAB2                                                                         061230  
0018.00 A1A                                                                                  061219  
0019.00 B2B                                                                                  061219  
0020.00 C3C                                                                                  061219  
0021.00 D4D                                                                                  061219  
0022.00 E5E                                                                                  061219  
0023.00 F6F                                                                                  061219  
0024.00 G7G                                                                                  061219  
0025.00 H8H                                                                                  061219  
0026.00 I9I

[ 本帖最后由 pantierui 于 2007-1-3 08:54 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-01-03 13:50 |只看该作者
你把我给你的上面的代码写到你的程序内
当AA=1的时候它就等于大写的壹
可以参见http://blog.chinaunix.net/u/20092/showart_218296.html
0001.00      E                    TAB1    1   10  1   TAB2    4                               061230  
0002.00      C                     MOVEL'1'       AA      1                                  061219  
0003.00      C                     MOVEL*BLANK    BB      1                                  061219  
0004.00      C                     Z-ADD1         X       20                                 061219  
0005.00      C           AA        LOKUPTAB1      TAB2           90                          061230  
0012.00      C   90      TAB2      DSPLY                                                     061230  
0015.00      C                     SETON                     LR                              061214  
0016.00      C                     RETRN                                                     061214  
0017.00 ** TAB1 TAB2                                                                         061230  
0018.00 0 零                                                                                  061219  
0019.00 1 壹                                                                                  061219  
0020.00 2 贰                                                                                  061219  
0021.00 3 叁                                                                                  061219  
0022.00 4 肆                                                                                  061219  
0023.00 5 伍                                                                                  061219  
0024.00 6 陆                                                                                  061219  
0025.00 7 柒                                                                                  061219  
0026.00 8 捌                                    
0026.00 9 玖

[ 本帖最后由 pantierui 于 2007-1-3 13:52 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2007-01-03 16:19 |只看该作者
对不起啊,大哥,我不知道您发的程式应该加在我程式的那里啊,而且您给我发的两段程式是不一样的,两个都要吗?


您能和我讲解下嘛,麻烦您了,谢谢您~~~

论坛徽章:
0
9 [报告]
发表于 2007-01-04 15:04 |只看该作者
55555555555555,别让他沉啊,还没解决啊~

论坛徽章:
0
10 [报告]
发表于 2007-01-08 08:51 |只看该作者
真的很不好意思啊,这个问题我真的解决不了,所以才不停的发,不停的发

现在上面催的很紧,请会的大侠们帮下忙嘛,小弟不盛感激~谢谢了~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP