关于我们通常在数中有0的处理最为困难,比如:10000001,100000000搞了一整天,还有些问题.贴上来,作为一天努力的记录.等再有时间继续.
ubuntu 12.04 32bit gcc 4.6.3
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*小数转换大写程序 1.0
* ljhhh0123@yahoo.com.cn 2013.5.12
* 输入的double值在小数点前13位和小数点后2位以内似乎是精确的.
* 用浮点来处理精确的银行钱数是肯定不行的.
* */
char *DaXie[]= {
"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"
};
char* Name[]= {
//小数点前16位.
"仟","佰","拾","万","仟","佰","拾","亿",
"仟","佰","拾","万","仟","佰","拾","圆",
"","角","分"
};
//第1个1为小数和点,第2个为结束符'\0'.
char buf[16+1+2+1];
int main() {
double d;static int t=0;int m;
int num;
scanf("%lf",&d);
printf("双精double值能表示为: ");
sprintf(buf,"%19.2lf",d);//按四位一段分段放入缓冲区,必须配合缓冲区大小.
if(23<strlen(buf)||d>999999999999999.99 || d<=0.0) {
printf("超出本程序表示范围,程序退出");
return 0;
}
fputs(buf,stdout);
fputs("\n",stdout);
fputs("大写表示为:",stdout);
for(num=0; buf[num]!='\0'; num+=4) {
int i;
char last;
if(buf[num]=='.') break;
if(buf[num]=='0' &&buf[num+1]=='0'&&buf[num+2]=='0'&&buf[num+3]=='0'){
if(t==0){
if(strcmp(Name[num+3],"兆")==0 || strcmp(Name[num+3],"亿")==0|| strcmp(Name[num+3],"圆")==0 ){
fputs(Name[num+i],stdout);
t=1;
continue;
}
}
if(buf[num+4]=='.') {fputs("圆",stdout); break;}
continue;
}
//大的整数,后面一大串0
m=num;
while(buf[m]!='.'){
if(buf[m]!='0') break;
m++;
}
if(buf[m]=='.'){
fputs("圆",stdout);
break;
}
//一次取四位,并判断0的位置,删掉多余的0.符合人们通常的念法.
for(i=0; i<4; i++) {
if(buf[num+i]==' ') continue;
if(buf[num+i]=='0') {
last='0';//记住前导的0
if(i==3) {//尾部的0,如4000,不需输出0,但如在万位则输出万.
fputs(Name[num+i],stdout);
break;
}
continue;
}
if(i==3) {
if(last=='0') {//将前导的0输出且只输入一个.
fputs(DaXie[last-'0'],stdout);
}
fputs(DaXie[buf[num+i]-'0'],stdout);
fputs(Name[num+i],stdout);
break;
}
if(last=='0') {//将前导的0输出且只输入一个.
fputs(DaXie[last-'0'],stdout);
}
last=buf[num+i];
fputs(DaXie[buf[num+i]-'0'],stdout);
fputs(Name[num+i],stdout);
}
}
//输出小数点后的两位.
for(num++; buf[num]!='\0'; num++) {
if(buf[num]=='0')continue;
fputs(DaXie[buf[num]-'0'],stdout);
fputs(Name[num],stdout);
}
fputs("整\n",stdout);
return 0;
}