阿拉伯数字小写金额转换成中文大写金额C程序说明
1、问题的提出
寒假帮同学交缴话费时,不经意间看到收据上同时有小写金额和大写金额,想想各种各样的票据诸如缴费收据、银行业务回单、商场销售凭证、专用发票等都是如此。若是手写的就列出了中文大写金额的货币单位(一般最大就个佰万),只要填写大写数字和划差就行;若是机器打印的,则是一次性将大写数字和货币单位一起打印出来,一般还会打印当前日期。嗯,那时便有了个想法,能否用C编程来实现这一打印过程呢(票据应该是定位的打印,不过好像有专门的票据打印机其原理我不怎么清楚所以暂时没涉及,只做简单的金额大小写转换),当然是指本人能否做到。想了想,有点眉目、有点麻烦,遂上网搜搜,方知并不是什么新奇的想法,能搜到一些其他语言作成的,却没搜到C语言的,哈有点开心啊,雄心壮志顿上心头,我也懒得再搜了,就由我自己来编写吧,印象中本人自主提出的第一个编程题吧,虽然没什么新意。斗志激昂啊,行动!又搜索一些中文大写金额的写法规定什么的,搜到一个《正确填写票据和结算凭证的基本规定》,很是详细,OK!就你了,遂以之为蓝本,另外一个问题就是最大到多少,当时那个被斗志充满的头脑,想啥想呢,就最大的吧,寻思好像就万亿最大了吧,再大似乎也没了,再说万亿就应该够用了,基本敲定了。直到这个暑假的这些天我才来把它实现,总是这么没效率啊。
上面废话一堆,已然历史。啊再罗嗦一下,之所以要写上中文大写金额,就是为了防止涂改,小写的话要是随意被人加几个0就不得了了(我也是看武林外传后才知道的,不过若是打印的好像在打印后也不会有此顾虑)。好,下面来看下我整理的中文大写金额写法的一些规范吧:
①、中文大写金额数字前应标明人民币字样(我先前标的人民币/RMB),大写金额数字应紧接人民币字样填写,不得留有空白。阿拉伯小写金额数字前面,均应填写人民币符号¥。中文大写金额数字应用正楷或行书填写,如壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、圆(元)、角、分、零、整(正)等字样。不得用一、二(两)、三、四、五、六、七、八、九、十、念、毛、另(或0)填写,不得自造简化字。
②、中文大写金额数字到圆(元)为止的,在圆(元)之后,应写整(正)字,在角之后,可以不写整(正)字(我没写)。大写金额数字有分的,分后面不写整(正)字。
③、阿拉伯数字小写金额数字中有0时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。阿拉伯数字中间有0时,中文大写要写零字(如¥1409.50,应写成人民币陆壹仟肆佰零玖元伍角);若阿拉伯数字中间连续有几个0时,中文大写金额中间可以只写一个零字(如¥6007.14,应写成人民币陆仟零柒元壹角肆分);但阿拉伯金额数字万位和元位是0,或者数字中间连续有几个0,万位、元位也是0,但千位、角位不是0时,中文大写金额中可以只写一个零字,也可以不写零字(我没写),(如¥107000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分);阿拉伯金额数字角位是0,而分位不是0时,中文大写金额元后面应写零字(如¥16409.02,应写成人民币壹万陆仟肆佰零玖元零贰分)。
2、检验程序
关于程序检验也可看成对上述规则的举例说明,所以就列了出来。截图部分为在vc++6.0下运行的结果。程序思路可直接看提供的源程序to_rmb.c,对于程序并无什么新奇,就是根据问题的提出进行的。我是在Dev-C++ 4.9.9.2下进行处理的,后来也在vc++6.0中运行了。我将输入作为字符串处理,然后分为整数和小数部分分别进行转换输出,由于输出中文的缘故,用数组、指针数组都没能成功输出显示(与字符编码相互的兼容有关),就用了switch语句模仿数组进行了对应的处理。对于各种不谨慎的输入,也做了些适当的处理,但有一定的局限性(对于小数部分只处理前两位,整数部分以0开头的直接做了0处理而忽略后面的整数部分,取小数点是从最大整数位开始搜索,不能用带分隔符的作为输入,如:123,456,789.00,等等)。若您发现有错误和值得改进之处,恳请指正,有新的思路,希望分享交流。
阿拉伯数字小写金额转换成中文大写金额程序检验
阿拉伯数字小写金额
部分输出(中文大写金额)
¥9870006504320.01
人民币/RMB玖万捌仟柒佰亿零陆佰伍拾万肆仟叁佰贰拾圆零壹分
¥11
人民币/RMB壹拾壹圆整
¥11.00
人民币/RMB壹拾壹圆整
¥400201.3
人民币/RMB肆拾万零贰佰零壹圆叁角
¥402001.3
人民币/RMB肆拾万贰仟零壹圆叁角
¥11.11
人民币/RMB壹拾壹圆壹角壹分
¥0.00
人民币/RMB零圆整
¥0.01
人民币/RMB零圆零壹分
¥0
人民币/RMB零圆整
¥4500.52.36
人民币/RMB肆仟伍佰圆伍角贰分
¥4500.5.236
人民币/RMB肆仟伍佰圆伍角,并提示错误
¥12345+.78
提示错误
¥9870006504320.01
人民币/RMB玖万捌仟柒佰亿零陆佰伍拾万肆仟叁佰贰拾圆零壹分
¥98700065043220
提示错误,并输出人民币/RMB玖捌万柒仟亿陆仟伍佰零肆万叁仟贰佰贰拾圆零壹分
¥0.12
人民币/RMB零圆壹角贰分
¥023.56
提示错误,并输出零圆伍角陆分
¥00.1
人民币/RMB零圆壹角
¥01.2
提示错误,并输出零圆贰角
¥02.23
提示错误.并输出零圆贰角叁分
2007-8-9
/* to_rmb.c
本程序将阿拉伯数字小写金额转换成中文大写金额!
Program reads a yuan string writting by the lowercase Arabic number
程序读取一用小写阿拉伯数字表示的人民币字符串
the strings will be converted into the amount of Chinese capital As an integral part and a small number
将阿拉伯数字小写金额作为整数和小数两部分依次转换成中文大写金额
print out the current date;
输出当前的年月日
print out the amount of Chinese capital.
输出中文大写金额
Need to be further revised.
程序需要进行进一步的修定。
Written by
R易, heroherer111@126.com,
August 2007.
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
//30是因为可能怕数组越界
#define N 30
void rmb_units(int k);
void big_write_num(int l);
void time_print(void);
int main()
{
char c[N],*p;
int a,i,j,len,len_integer=0,len_decimal=0; //len_integer整数部分长度,len_decimal小数部分长度
printf("----------------------------------------*---------------------------------------/n");
printf("*****|-----------*本程序将阿拉伯数字小写金额转换成中文大写金额!*----------|*****/n");
printf("----------------------------------------*---------------------------------------/n/n");
time_print(); //输出当前年月日
printf("please input (阿拉伯数字小写金额): ¥");
scanf("%s",c);
printf("/n/n");
p=c;
len=strlen(p);
/*求出整数部分的长度*/
for(i=0;i<=len-1 && *(p+i)<='9' && *(p+i)>='0';i++);
if(*(p+i)=='.' || *(p+i)=='/0') //*(p+i)=='/0'没小数点的情况
len_integer=i;
else
{
printf("/n/n!!!!---------# Error: 输入有错误,整数部分含有错误的字符!---------!!!!/n/n");
system("pause");
exit(EXIT_FAILURE);
}
if(len_integer>13)
{
printf("!---------------超过范围,最大万亿!整数部分最多位!程序暂停!---------------!/n");
system("pause");
printf("/n!---------程序继续执行,注意:超过万亿部分只是简单读出数字的中文大写!----------!/n/n");
}
printf("/n===================================转换开始!===================================/n/n");
printf("¥%s 的中文大写金额如下所示:/n/n人民币/RMB",c);
/*转换整数部分*/
for(i=0;i<len_integer;i++)
{
a=*(p+i)-'0';
if(a==0)
{
if(i==0)
{
if(*(p+1)!='.' && *(p+1)!='/0' && *(p+1)!='0')
{
printf("/n/n!------------输入有错误!第一位为而后整数部分有非字符,请检查!---=--------!/n/n");
system("pause");
printf("/n!--------------程序继续执行,注意:整数部分的剩下部分将被忽略!----------------!/n/n");
}
printf("零圆");
break; //若第一个是则忽略其他整数部分
}
else if(*(p+i+1)!='0' && i!=len_integer-5 && i!=len_integer-1 && i!=len_integer-9) //圆、万、亿位为时选择不加零 {
{
printf("零");
continue;
}
else if(i==len_integer-1 || i==len_integer-5 || i==len_integer-9) //圆万亿单位不能掉
{
rmb_units(len_integer+1-i);
continue;
}
else
continue;
}
big_write_num(a); //阿拉伯数字中文大写输出
rmb_units(len_integer+1-i); //人民币货币单位中文大写输出
}
/*求出小数部分的长度*/
len_decimal=len-len_integer-1;
if(len_decimal<0)
{
len_decimal=0;
printf("整"); //或正
}
if(len_decimal>2) //只取两位小数
len_decimal=2;
//printf("%d----%d-----%d/n",len,len_integer,len_decimal);
p=c;
/*转换小数部分*/
for(j=0;j<len_decimal;j++)
{
a=*(p+len_integer+1+j)-'0'; //定位到小数部分,等价于a=*(p+len-len_decimal+j)-'0';
if(a<0 || a>9)
{
printf("/n/n!!!!---------# Error: 输入有错误,小数部分含有错误的字符!---------!!!!/n/n");
system("pause");
exit(EXIT_FAILURE);
}
if(a==0)
{
if(j+1<len_decimal)
{
if(*(p+len_integer+j+2)!='0')
printf("零");
else
{
printf("整");
break;
}
}
continue;
}
big_write_num(a);
rmb_units(1-j);
}
printf("/n/n");
printf("===================================转换完成!===================================/n/n");
system("pause");
}
/*人民币货币单位中文大写输出*/
void rmb_units(int k)
{
//相当于const char rmb_units[]="fjysbqwsbqisbqw";
//"分角圆拾佰仟万拾佰仟亿拾佰仟万";
switch(k)
{
case 3:case 7:case 11: printf("拾");break;
case 4:case 8:case 12: printf("佰");break;
case 5:case 9:case 13: printf("仟");break;
case 6: case 14: printf("万");break;
case 10: printf("亿");break;
case 2: printf("圆");break;
case 1: printf("角");break;
case 0: printf("分");break;
default: break;
}
}
/*阿拉伯数字中文大写输出*/
void big_write_num(int l)
{
//相当于const char big_write_num[]="0123456789";
//"零壹贰叁肆伍陆柒捌玖"
switch(l)
{
case 0:printf("零");break;
case 1:printf("壹");break;
case 2:printf("贰");break;
case 3:printf("叁");break;
case 4:printf("肆");break;
case 5:printf("伍");break;
case 6:printf("陆");break;
case 7:printf("柒");break;
case 8:printf("捌");break;
case 9:printf("玖");break;
default:break;
}
}
/*输出当前年月日,相关类型和函数声明参见<time.h>*/
void time_print(void)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime ); //获取时间
//printf("%d",rawtime);
timeinfo = localtime ( &rawtime );//转换为当地时间tm结构
//直接打印tm结构的元素,tm_year从1900年计算,所以要加1900,月tm_mon,从0计算,所以要加1
printf ( "%d年%02d月%02d日/n/n",1900+timeinfo->tm_year, 1+timeinfo->tm_mon,timeinfo->tm_mday);
}
0 0