/** * @brief 将源字符串中的小写金额转换为大写格式 * * @param dest 目的字符串 * @param src 小写金额字符串 * @return * - NULL 源字符串的格式错误,返回NULL * - 非NULL 目的字符串的首地址 * @note 转换根据:中国人民银行会计司编写的最新《企业、银行正确办理支付结算 * 指南》的第114页-第115页 */ char* chineseFee( char* dest, 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; char* pDest = dest; char* pSrc = src; int* pInt = feeInfo.integer; int* pDec = feeInfo.decimal; //初始化 feeInfo.sizeInt = 0; feeInfo.sizeDecimal = 0; feeInfo.minus = 0; //分析字符串 while( 1 ) { switch ( *pSrc ) { 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 ( *pSrc == '0' && status == ZEROINT )//|| status == START ) ) { status = ERROR; break; } if ( status == MINUS || status == START || status == INTEGER ) { if ( *pSrc == '0' && ( status == MINUS || status == START ) ) status = ZEROINT; else status = INTEGER; *pInt = (*pSrc) - 48; ++pInt; ++feeInfo.sizeInt; } else if ( status == DECIMAL || status == DECIMALfRACTION ) { status = DECIMALfRACTION; *pDec = (*pSrc) - 48; ++pDec; ++feeInfo.sizeDecimal; } else { status =ERROR; } break; case '.' : status = ( status == INTEGER || status == ZEROINT ) ? DECIMAL : ERROR; break; case '' : status = ( status == INTEGER || status == DECIMALfRACTION || status == ZEROINT ) ? END : ERROR; break; default : status = ERROR; } if ( status == END ) break; else if ( status == ERROR ) return NULL; ++pSrc; } //只有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 ] ); } } return dest; } |