人民币金额大小写转换

上一篇 / 下一篇  2015-05-26 14:27:48

该代码转自别的网页,对原作者表示感谢!但是原来的代码不能直接在VC6.0环境下运行,经过本人简单调式,现已能正常运行,同时在linux gcc下运行正常。

/**
* @brief 将源字符串中的小写金额转换为大写格式
*
* @param dest 目的字符串
* @param *src 小写金额字符串
* @return 
* - NULL 源字符串的格式错误,返回NULL
* - 非NULL 目的字符串的首地址
* @note 转换根据:中国人民银行会计司编写的最新《企业、银行正确**支付结算
*       指南》的第114页-第115页
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<memory.h>
char* chineseFee(char *pDest,char *src)
{
   enum{
        START,                 //开始
        MINUS,                 //负号
        ZEROINT,               //0整数
        INTEGER,               //整数
        DECIMAL,               //小数点
        DECIMALfRACTION,       //小数位
        END,                   //结束
        ERROR                  //错误
    } status = START;
    struct
    {
        int minus;             //0为正,1为负
        int sizeInt;
        int sizeDecimal;
        int integer[10];
        int decimal[10];
    } feeInfo;


    char* NumberChar[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
    char* UnitChar[] ={ "整", "圆", "拾", "佰","仟", "万", "拾", "佰", "仟", "亿", 
          "拾", "佰", "仟", "万亿", "拾", "佰", "仟", "亿亿", 
          "角", "分", "负", "人民币" };
           
    int      i, j,size;             //循环变量
    int      zeroTag        = 0,    //0标志
             decZeroTag     = 0;
     
    int*     pInt           = feeInfo.integer;
    int*     pDec           = feeInfo.decimal;
     
    //初始化
    feeInfo.sizeInt        = 0;
    feeInfo.sizeDecimal    = 0;
    feeInfo.minus          = 0;
     
    //分析字符串
    while( 1 )
    {
        switch ( *src )
        {
            case '-' :
                status = ( status == START ) ? MINUS : ERROR;
                feeInfo.minus = ( status == MINUS ) ? 1 : 0;
                break;
            case '1' :
            case '2' :
            case '3' :
            case '4' :
            case '5' :
            case '6' :
            case '7' :
            case '8' :
            case '9' :
            case '0' :
                if ( *src == '0' && status == ZEROINT )//|| status == START ) )
                {
                    status = ERROR;
                    break;
                }
                if ( status == MINUS || status == START || status == INTEGER )
                {
                    if ( *src == '0' && ( status == MINUS || status == START ) )
                        status = ZEROINT;
                    else
                        status = INTEGER;
                    *pInt = (*src) - 48;
                    ++pInt;
                    ++feeInfo.sizeInt;
                }
                else if ( status == DECIMAL || status == DECIMALfRACTION )
                {
                    status = DECIMALfRACTION;
                    *pDec = (*src) - 48;
                    ++pDec;
                    ++feeInfo.sizeDecimal;
                }
                else
                {
                    status =ERROR;
                }
                break;
            case '.' :
                status = ( status == INTEGER || status == ZEROINT ) 
                         ? DECIMAL : ERROR;
                break;
            case '\0' :
                status = ( status == INTEGER || status == DECIMALfRACTION 
                           || status == ZEROINT ) ? END : ERROR;
                break;
            default :
                status = ERROR;
        }
        if ( status == END ) 
            break;
        else if ( status == ERROR ){
            return NULL;
    //printf("NULL!"); 
   }
        ++src;
    }
     
    //只有1位小数时,设置百分位为0,使下面代码不必区分这两种情况
    if ( feeInfo.sizeDecimal == 1 )
    {
        feeInfo.decimal[ 1 ] = 0;
        ++feeInfo.sizeDecimal;
    }


    //判断是否需要打印小数部分,有小数部且十分位和百分位不都为0
    //需要打印小数部时,zeroTag设为0,否则设为1
    if ( feeInfo.sizeDecimal == 0                                 //没有小数
        || ( !feeInfo.decimal[ 0 ] && !feeInfo.decimal[ 1 ] ) )   //小数部都为0
        decZeroTag = 1;
    else
        decZeroTag = 0;
         
    //printf( "int size: %d    decimal size: %d\n", feeInfo.sizeInt, feeInfo.sizeDecimal );
     
    strcpy( pDest, UnitChar[ 21 ] );                  //初始化目标字符串-人民币
     
    if ( feeInfo.minus ) strcat( pDest, UnitChar[ 20 ] );    //负号
         
    //处理整数部分
    size = feeInfo.sizeInt;
    for( i = 0; i < size; ++i )
    {
        j = size - i - 1 & 0x3;                              //j = 0时为段尾
        if ( feeInfo.integer[ i ] == 0 && j )                //处理非段尾0
        {
            zeroTag = 1;
        }
        else if ( feeInfo.integer[ i ] == 0 && !j )          //处理段尾0
        {
            if ( feeInfo.sizeInt == 1 && decZeroTag )        //特别处理个位0
                strcat( pDest, NumberChar[ feeInfo.integer[ i ] ] );
            if ( feeInfo.sizeInt != 1 || decZeroTag )
                strcat( pDest, UnitChar[ size - i ] );
            zeroTag = 0;
        }
        else                                                 //处理非0
        {
            if ( zeroTag )
            {
                strcat( pDest, NumberChar[ 0 ] );
                zeroTag = 0;
            }
            strcat( pDest, NumberChar[ feeInfo.integer[ i ] ] );
            strcat( pDest, UnitChar[ size - i ] );
            if ( !j ) zeroTag = 0;                      //如果是段尾,设为非标志
        }
    }
     
    if ( decZeroTag )
    {
        strcat( pDest, UnitChar[ 0 ] );//没有小数部,打印"整"字符
    }
    else
    {
        //十分位
        if ( feeInfo.decimal[ 0 ] )
        {
            strcat( pDest, NumberChar[ feeInfo.decimal[ 0 ] ] );
            strcat( pDest, UnitChar[ 18 ] );
        }
        else if ( feeInfo.sizeInt != 1 || feeInfo.integer[ 0 ] )
        {
            strcat( pDest, NumberChar[ feeInfo.decimal[ 0 ] ] );
        }
         
        //百分位不为0时
        if ( feeInfo.decimal[ 1 ] )     
        {
            strcat( pDest, NumberChar[ feeInfo.decimal[ 1 ] ] );
            strcat( pDest, UnitChar[ 19 ] );
        }
    }
    //printf("%s\n",pDest);
    return pDest;
//printf("=====%s\n",pDest);
}
int main()
{
char pDest[50];
char num[10];
memset(num,0,10);
memset(pDest,0,50);
    strcpy(num,"102030.01");
//dest1=chineseFee(num);
printf("======%s\n",chineseFee(pDest,num));

}


TAG:

 

评分:0

我来说两句

日历

« 2024-04-13  
 123456
78910111213
14151617181920
21222324252627
282930    

我的存档

数据统计

  • 访问量: 1981
  • 日志数: 2
  • 建立时间: 2015-05-25
  • 更新时间: 2015-05-27

RSS订阅

Open Toolbar