免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5490 | 回复: 11
打印 上一主题 下一主题

[C] 将数字转换成汉语大写 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-30 20:31 |只看该作者 |倒序浏览
本帖最后由 时间看来 于 2012-12-01 23:18 编辑

看到有讨论用shell script写这个,学习了哈。sed,gawk复制的用法还没有搞懂~
尝试了下用c写,请多多指教!欢迎您贴出您的代码,供我们菜鸟学习。
  1. /*
  2. *输入12,如何转换成壹拾贰,输入1020,转成壹千零贰拾
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>

  7. void get4num(char *dest, char *src);
  8. void output4num(char *src);
  9. int output_unit(int left_bits);

  10. char *my_array[10] = {"零","壹","贰","叁","肆",\
  11.                           "伍","陆","柒","捌","玖"};
  12. char *my_unit[5] = {"拾","佰","仟","万","亿"};
  13. int FLAG_FIRST;
  14. int
  15. main(int argc, char *argv[])
  16. {
  17.         /*test my_array*/
  18.         int i;
  19.         for(i=0; i<10; i++){
  20.                 printf("%s\n", *(my_array+i));
  21.         }

  22.         char input_num[100];
  23.         printf("input_num:\n");
  24.         scanf("%s", input_num);
  25.         printf("%s\n", input_num);
  26.        
  27.         int input_len = strlen(input_num);
  28.         char nums_4[6];

  29.         /*output first nums*/
  30.         FLAG_FIRST = 1;
  31.         int first_num = input_len % 4;
  32.         if(first_num != 0){
  33.                 strncpy(nums_4, input_num, first_num);
  34.                 output4num(nums_4);
  35.                 output_unit(input_len);
  36.         }

  37.         /*output the left 4 nums*/
  38.         FLAG_FIRST = 1;
  39.         for(i=first_num; i<input_len; i+=4){
  40.                 get4num(nums_4, input_num+i);
  41.                 output4num(nums_4);
  42.                 output_unit(input_len-i);
  43.                 FLAG_FIRST = 0;
  44.         }

  45.         printf("\0");
  46.         return 0;
  47. }

  48. /*
  49. *get 4 numbers
  50. */
  51. void
  52. get4num(char *dest, char *src)
  53. {
  54.         int i = 4;
  55.         strncpy(dest, src, i);
  56. }

  57. /*
  58. * output 4 numbers
  59. */
  60. void
  61. output4num(char *src)
  62. {
  63.         int i, j;
  64.         int num, nums[4];
  65.         num = atoi(src);
  66.         j = strlen(src);

  67.         /*low number is at low place*/
  68.         for(i=0; i<4; i++){
  69.                 nums[i] = (num % 10);
  70.                 num /= 10;
  71.         }

  72.         /*output first nums*/
  73.         if(nums[j-1] == 0){
  74.                 if((j == 4) && (FLAG_FIRST == 0)){
  75.                         printf("%s", *(my_array+nums[j-1]));
  76.                 }
  77.         }else{
  78.                 printf("%s", *(my_array+nums[j-1]));
  79.                 printf("%s", *(my_unit+j-2));
  80.         }

  81.         /*output number and unit*/
  82.         for(i=j-2; i>=1; i--){
  83.                 if(nums[i] == 0){
  84.                         if(nums[i+1] != 0){
  85.                                 printf("%s", *(my_array+nums[i]));
  86.                         }
  87.                 }else{
  88.                         printf("%s", *(my_array+nums[i]));
  89.                         printf("%s", *(my_unit+i-1));
  90.                 }
  91.         }
  92.         if(nums[0] != 0){
  93.                 printf("%s", *(my_array+nums[i]));
  94.         }
  95. }

  96. /*
  97. * output the unit of 4 nums
  98. */
  99. int
  100. output_unit(int left_bits)
  101. {
  102.         int m, n;
  103.         m = (left_bits-1) / 4;
  104.         switch(m){
  105.                 case 0:
  106.                         return 0;
  107.                 case 1:
  108.                         printf("%s", my_unit[3]);
  109.                         return 0;
  110.                 default:
  111.                         for(n=m; n>=2; n--){
  112.                                 printf("%s", my_unit[4]);
  113.                         }
  114.         }

  115.         printf(",");
  116. }


复制代码
input_num:
9283749817509843219827409812365908
9283749817509843219827409812365908
玖拾贰亿亿亿亿亿亿亿,捌仟叁佰柒拾肆亿亿亿亿亿亿,玖仟捌佰壹拾柒亿亿亿亿亿,伍仟零玖拾捌亿亿亿亿,肆仟叁佰贰拾壹亿亿亿,玖仟捌佰贰拾柒亿亿,肆仟零玖拾捌亿,壹仟贰佰叁拾陆万伍仟玖佰零捌

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012.12.1
非常感谢楼下的回复,陪我写玩具程序。

发现我上面的程序每4位输出的单位上万亿后都是错的。把重写了int output_unit(int left_bits),还有修改了穿过来的left_bits是4的整数倍。
根据人的读数习惯(以4个位数为一个单元),第一感觉也就这么写了。相信还有跟好的方法。
2楼的就是根据每位数来判断单位,不过我编译运行你的程序后,输出是乱码,这个我没有搞明白。我可是很想抓你小辫子哦!哇咔咔~对你再次表示感谢。
  1. /*
  2. *输入12,如何转换成壹拾贰,输入1020,转成壹千零贰拾
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>

  7. void get4num(char *dest, char *src);
  8. void output4num(char *src);
  9. int output_unit(int left_bits);

  10. char *my_array[10] = {"零","壹","贰","叁","肆",\
  11.                           "伍","陆","柒","捌","玖"};
  12. char *my_unit[5] = {"拾","佰","仟","万","亿"};
  13. int FLAG_FIRST;
  14. int
  15. main(int argc, char *argv[])
  16. {
  17.         /*test my_array*/
  18.         int i;
  19.         for(i=0; i<10; i++){
  20.                 printf("%s\n", *(my_array+i));
  21.         }

  22.         char input_num[100];
  23.         printf("input_num:\n");
  24.         scanf("%s", input_num);
  25.         printf("%s\n", input_num);
  26.        
  27.         int input_len = strlen(input_num);
  28.         char nums_4[6];

  29.         /*output first nums*/
  30.         FLAG_FIRST = 1;
  31.         int first_num = input_len % 4;
  32.         if(first_num != 0){
  33.                 strncpy(nums_4, input_num, first_num);
  34.                 output4num(nums_4);
  35.                 output_unit(input_len - first_num);
  36.         }

  37.         /*output the left 4 nums*/
  38.         FLAG_FIRST = 1;
  39.         for(i=first_num; i<input_len; i+=4){
  40.                 get4num(nums_4, input_num+i);
  41.                 output4num(nums_4);
  42.                 output_unit(input_len - i - 4);
  43.                 FLAG_FIRST = 0;
  44.         }

  45.         printf("\0\0");
  46.         return 0;
  47. }

  48. /*
  49. *get 4 numbers
  50. */
  51. void
  52. get4num(char *dest, char *src)
  53. {
  54.         int i = 4;
  55.         strncpy(dest, src, i);
  56. }

  57. /*
  58. * output 4 numbers
  59. */
  60. void
  61. output4num(char *src)
  62. {
  63.         int i, j;
  64.         int num, nums[4];
  65.         num = atoi(src);
  66.         j = strlen(src);

  67.         /*low number is at low place*/
  68.         for(i=0; i<4; i++){
  69.                 nums[i] = (num % 10);
  70.                 num /= 10;
  71.         }

  72.         /*output first nums*/
  73.         if(nums[j-1] == 0){
  74.                 if((j == 4) && (FLAG_FIRST == 0)){
  75.                         printf("%s", *(my_array+nums[j-1]));
  76.                 }
  77.         }else{
  78.                 printf("%s", *(my_array+nums[j-1]));
  79.                 printf("%s", *(my_unit+j-2));
  80.         }

  81.         /*output number and unit*/
  82.         for(i=j-2; i>=1; i--){
  83.                 if(nums[i] == 0){
  84.                         if(nums[i+1] != 0){
  85.                                 printf("%s", *(my_array+nums[i]));
  86.                         }
  87.                 }else{
  88.                         printf("%s", *(my_array+nums[i]));
  89.                         printf("%s", *(my_unit+i-1));
  90.                 }
  91.         }
  92.         if(nums[0] != 0){
  93.                 printf("%s", *(my_array+nums[i]));
  94.         }
  95. }

  96. /*
  97. * output the unit of 4 nums
  98. */
  99. int
  100. output_unit(int left_bits)
  101. {
  102.         int m, n;
  103.         /*the last one*/
  104.         if(left_bits < 4){
  105.                 return 0;
  106.         } else{
  107.                 m = left_bits % 8;
  108.                 switch(m){
  109.                         case 4:
  110.                                 printf("%s", my_unit[3]);
  111.                                 break;
  112.                         case 0:
  113.                                 n = left_bits / 8;
  114.                                 for(m=0; m<n; m++){
  115.                                         printf("%s", my_unit[4]);
  116.                                 }
  117.                 }
  118.         }

  119.         printf(",");
  120.         return 0;
  121. }


复制代码
input_num:
123456789012345678901234567890
123456789012345678901234567890
壹拾贰万,叁仟肆佰伍拾陆亿亿亿,柒仟捌佰玖拾万,壹仟贰佰叁拾肆亿亿,伍仟陆佰柒拾捌万,玖仟零壹拾贰亿,叁仟肆佰伍拾陆万,柒仟捌佰玖拾

论坛徽章:
36
子鼠
日期:2013-08-28 22:23:29黄金圣斗士
日期:2015-12-01 11:37:51程序设计版块每日发帖之星
日期:2015-12-14 06:20:00CU十四周年纪念徽章
日期:2015-12-22 16:50:40IT运维版块每日发帖之星
日期:2016-01-25 06:20:0015-16赛季CBA联赛之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之福建
日期:2016-04-07 11:25:2215-16赛季CBA联赛之青岛
日期:2016-04-29 18:02:5915-16赛季CBA联赛之北控
日期:2016-06-20 17:38:50技术图书徽章
日期:2016-07-19 13:54:03程序设计版块每日发帖之星
日期:2016-08-21 06:20:00
2 [报告]
发表于 2012-11-30 22:28 |只看该作者
本帖最后由 cokeboL 于 2012-12-01 10:56 编辑

只有一个功能不用把那个write_unit()拆出来,写完懒得改了
  1. #include <stdio.h>
  2. #include <string.h>

  3. int write_unit(int len, char *dst)
  4. {
  5.         char tmp[32] = {0};
  6.         int i;
  7.         switch(len % 4)
  8.         {
  9.                 case 0:
  10.                         strncpy(tmp, "仟", 2);
  11.                         break;
  12.                 case 1:
  13.                         if(len % 8 == 1){
  14.                                 for(i = 0; i < len/8; i++)
  15.                                         strncpy(tmp + i*2, "亿", 2);
  16.                         }
  17.                         else{
  18.                                 strncpy(tmp, "万", 2);
  19.                         }
  20.                         break;
  21.                 case 2:
  22.                         strncpy(tmp, "拾", 2);
  23.                         break;
  24.                 case 3:
  25.                         strncpy(tmp, "佰", 2);
  26.                         break;
  27.         }
  28.         strcpy(dst, tmp);
  29.         return strlen(tmp);
  30. }
  31.                                
  32. char *str_convert(const char *src, char *dst)
  33. {
  34.         char *tmp = src;
  35.         int i, write_len = 0;
  36.         char number[] = "零壹贰叁肆伍陆柒捌玖";

  37.         printf("src: %s\n", src);
  38.         if(*tmp <= '0')
  39.                 return NULL;
  40.         while(*tmp){
  41.                 if(*tmp < '0' || *tmp > '9')
  42.                         return NULL;
  43.                 tmp++;
  44.         }

  45.         tmp = dst;
  46.         for(i = 0; i < strlen(src); i++){
  47.                 strncpy(tmp + write_len, number + (src[i] - '0') * 2, 2);
  48.                 write_len += 2;
  49.                 write_len += write_unit(strlen(src + i), tmp + write_len);
  50.         }
  51.         if(('0' == src[i-1]) && (strlen(src) > 1))
  52.                 dst[write_len - 2] = 0;

  53.         printf("dst: %s\n", dst);
  54.         return dst;
  55. }

  56. int main()
  57. {
  58.         char tmp[100] = {0};
  59.         char tmp2[100] = {0};
  60.         scanf("%s", tmp);
  61.         str_convert(tmp, tmp2);
  62. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2012-12-01 23:20 |只看该作者
回复 2# cokeboL


非常感谢你的回复,陪我写玩具程序。

发现我上面第一个程序每4位输出的单位上万亿后都是错的。把重写了int output_unit(int left_bits),还有修改了穿过来的left_bits是4的整数倍。
根据人的读数习惯(以4个位数为一个单元),第一感觉也就这么写了。相信还有跟好的方法。
2楼的就是根据每位数来判断单位,不过我编译运行你的程序后,输出是乱码,这个我没有搞明白。
我可是很想抓你小辫子哦!哇咔咔~对你再次表示感谢。

论坛徽章:
36
子鼠
日期:2013-08-28 22:23:29黄金圣斗士
日期:2015-12-01 11:37:51程序设计版块每日发帖之星
日期:2015-12-14 06:20:00CU十四周年纪念徽章
日期:2015-12-22 16:50:40IT运维版块每日发帖之星
日期:2016-01-25 06:20:0015-16赛季CBA联赛之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之福建
日期:2016-04-07 11:25:2215-16赛季CBA联赛之青岛
日期:2016-04-29 18:02:5915-16赛季CBA联赛之北控
日期:2016-06-20 17:38:50技术图书徽章
日期:2016-07-19 13:54:03程序设计版块每日发帖之星
日期:2016-08-21 06:20:00
4 [报告]
发表于 2012-12-01 23:30 |只看该作者
本帖最后由 cokeboL 于 2012-12-01 23:31 编辑

回复 3# 时间看来


不知道你用啥编译的。。。我的运行输入:1234567890,打印出来的是:

src: 1234567890
dst: 壹拾贰亿叁仟肆佰伍拾陆万柒仟捌佰玖拾

把单位的算法先明确了就能写明白了。我的如果有错你直接修改下就行了,我那拆出来的函数也没必要,就一转换函数,挪到里面就行了。

论坛徽章:
0
5 [报告]
发表于 2012-12-02 11:21 |只看该作者
这个有点实用价值,但也懒得写代码也懒得分析,提供一下想法:
1、先把数字逐个压入一个栈中,然后再逐个弹出来,并按新规则重新解释,得到一个字符串,然后反一下次序输出。
2、重新解释新规则时,使用状态机或者状态迁移表来帮助分析,然后再翻译成程序。
好的代码应该也会超过100行。

论坛徽章:
0
6 [报告]
发表于 2012-12-02 11:28 |只看该作者
本帖最后由 时间看来 于 2012-12-02 11:38 编辑

回复 4# cokeboL


    嗯,我是gcc4.1.2编译的。在你提示处理好单位后,我又重新写了一个。
    差不多是一个一个数字读,不是先划分4个数为一组。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. char *my_array[10] = {"零","壹","贰","叁","肆",\
  5.      "伍","陆","柒","捌","玖"};
  6. char *my_unit[5] = {"拾","佰","仟","万","亿"};

  7. void
  8. output_unit(int position)
  9. {
  10.         if(position == 1){
  11.                 return;
  12.         }

  13.         int left_bits = position -1;
  14.         int i, many_yi;
  15.         int case_unit;
  16.         if(left_bits % 8 == 0){
  17.                 many_yi = left_bits / 8;
  18.                 for(i=0; i<many_yi; i++){
  19.                         printf("%s", my_unit[4]);
  20.                 }
  21.                 printf(";");
  22.         } else{
  23.                 case_unit = left_bits % 4;
  24.                 switch(case_unit){
  25.                     case 0:
  26.                                 printf("%s,", my_unit[3]);
  27.                                 break;
  28.                     case 1:
  29.                         printf("%s", my_unit[0]);
  30.                             break;
  31.                     case 2:
  32.                         printf("%s", my_unit[1]);
  33.                         break;
  34.                     case 3:
  35.                         printf("%s", my_unit[2]);
  36.                             break;
  37.                 }
  38.         }
  39. }

  40. int
  41. str_convert(char *src)
  42. {
  43.         int i;
  44.         /*check the input string*/
  45.         int src_len = strlen(src);
  46.         if(src_len < 1){
  47.                 printf("dont't have enough digital");
  48.         }

  49.         /*keep the string is legal*/
  50.         for(i=0; i<src_len; i++){
  51.                 if(*(src+i) >= '0' && *(src+i) <= '9'){
  52.                         continue;
  53.                 } else{
  54.                         printf("the number is illegal\n");
  55.                         return 0;
  56.                 }
  57.         }

  58.         /*output Chinese*/
  59.         int first_bit = 0;
  60.         for(i=0; i<src_len && *(src+i) == '0'; i++){
  61.                 ;
  62.         }
  63.         first_bit = i;

  64.         char *cur_bit;
  65.         int cur_dig;
  66.         for(i=first_bit; i<src_len; i++){
  67.                 cur_bit = src + i;
  68.                 cur_dig = *cur_bit - '0';
  69.                 printf("%s",*(my_array + cur_dig));
  70.                 output_unit(src_len - i);
  71.         }

  72.         printf("\n");
  73.         return 0;
  74. }

  75. int main(int argc, char *argv[])
  76. {
  77.         char tmp[100];
  78.         printf("input a number\n");
  79.         scanf("%s", tmp);
  80.         printf("src:%s\n", tmp);
  81.         str_convert(tmp);

  82.         fflush(stdout);
  83.         return 0;
  84. }
复制代码
input a number
src:00123 4567 | 8901 2345 | 6789 0123 | 4567 8901
壹佰贰拾叁万,肆仟伍佰陆拾柒亿亿亿;捌仟玖佰零拾壹万,贰仟叁佰肆拾伍亿亿;陆仟柒佰捌拾玖万,零仟壹佰贰拾叁亿;肆仟伍佰陆拾柒万,捌仟玖佰零拾壹

论坛徽章:
0
7 [报告]
发表于 2012-12-02 11:30 |只看该作者
回复 5# zighouse


    嗯,用递归,应该不错。
    我下面给的代码不超过100行啊。谢谢你的夸奖。哇咔咔~

论坛徽章:
0
8 [报告]
发表于 2012-12-02 11:34 |只看该作者
回复 7# 时间看来


    递归等同于栈的操作。

论坛徽章:
0
9 [报告]
发表于 2012-12-02 11:40 |只看该作者
回复 8# zighouse


    嗯,就是。
   

论坛徽章:
0
10 [报告]
发表于 2012-12-02 11:51 |只看该作者
回复 2# cokeboL


    比较奇怪,我输入0123的时候,并没有得到“零仟壹佰贰拾叁”,可能也与我开发环境的相关。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP