该代码转自别的网页,对原作者表示感谢!但是原来的代码不能直接在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));
}