程式碼練習——數字轉中文
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> char* pcFig[20] = {"零","一","二","三","四","五","六","七","八","九","十","百","千","萬","億"}; int one = 1; char tens[50]; char hundreds[50]; char thousands[50]; char wan[50]; char yi[50]; char * OneToStr(int input) { if((input > 0) && (input <10)) { return pcFig[input]; } return ""; } char * TensToStr(int input, int zero) { tens[0]='\0'; int num = input / 10; int left = input % 10; if( num == 0 ) { if(zero) { strcat(tens, "零"); } strcat(tens, OneToStr(left)); } else { if(num == 1) { if(one) { strcat(tens, "一"); strcat(tens, "十"); } else { strcat(tens, "十"); one = 1; } } else { strcat(tens, OneToStr(num)); strcat(tens, "十"); } strcat(tens, OneToStr(left)); } return tens; } char * HundredsToStr(int input, int zero) { hundreds[0]='\0'; int num = input / 100; int left = input % 100; if(num==0) { if(zero) { strcat(hundreds, "零"); } strcat(hundreds, TensToStr(left, 0)); } else { strcat(hundreds, OneToStr(num)); strcat(hundreds, "百"); if(left == 0) { return hundreds; } strcat(hundreds, TensToStr(left, 1)); } return hundreds; } char * ThousandsToStr(int input, int zero) { thousands[0]='\0'; int num = input / 1000; int left = input % 1000; if(input>19) { one = 1; } if(num==0) { if(zero) { strcat(thousands, "零"); } strcat(thousands, HundredsToStr(left, 0)); } else { strcat(thousands, OneToStr(num)); strcat(thousands, "千"); if(left == 0) { return thousands; } strcat(thousands, HundredsToStr(left, 1)); } return thousands; } char * WanToStr(unsigned long input, int zero) { wan[0] = '\0'; int num = input / 10000; int left = input % 10000; if(num==0) { if(zero) { strcat(wan, "零"); } strcat(wan, ThousandsToStr(left, 0)); } else { strcat(wan, ThousandsToStr(num, 0)); strcat(wan, "萬"); one = 1; if(left == 0) { return wan; } strcat(wan, ThousandsToStr(left, 1)); } return wan; } char * YiToStr(unsigned long input, int zero) { yi[0] = '\0'; unsigned long num = input / 100000000; unsigned long left = input % 100000000; if(num==0) { if(zero) { strcat(yi, "零"); } strcat(yi, WanToStr(left, 0)); } else { strcat(yi, ThousandsToStr(num, 0)); strcat(yi, "億"); one = 1; if(left == 0) { return yi; } if(left < 10000000 && left > 9999) { strcat(yi, "零"); } strcat(yi, WanToStr(left, 1)); } return yi; } char * ConvertToChinese(unsigned long input) { one = 0; if(input == 0) { return (char*)"零"; } return YiToStr(input, 0); } #define TEST(IN, EXP) \ { \ printf("%s\n",ConvertToChinese(IN));\ assert(strcmp(ConvertToChinese(IN), EXP) == 0);\ }; int main() { TEST(0, "零"); TEST(1, "一"); TEST(2, "二"); TEST(3, "三"); TEST(4, "四"); TEST(5, "五"); TEST(6, "六"); TEST(7, "七"); TEST(8, "八"); TEST(9, "九"); TEST(10, "十"); TEST(11, "十一"); TEST(20, "二十"); TEST(99, "九十九"); TEST(100, "一百"); TEST(101, "一百零一"); TEST(110, "一百一十"); TEST(111, "一百一十一"); TEST(1000, "一千"); TEST(1001, "一千零一"); TEST(1010, "一千零一十"); TEST(1011, "一千零一十一"); TEST(1100, "一千一百"); TEST(1101, "一千一百零一"); TEST(1110, "一千一百一十"); TEST(1111, "一千一百一十一"); TEST(10000, "一萬"); TEST(10001, "一萬零一"); TEST(10010, "一萬零一十"); TEST(10011, "一萬零一十一"); TEST(10100, "一萬零一百"); TEST(10101, "一萬零一百零一"); TEST(10110, "一萬零一百一十"); TEST(10111, "一萬零一百一十一"); TEST(11000, "一萬一千"); TEST(11001, "一萬一千零一"); TEST(11010, "一萬一千零一十"); TEST(11011, "一萬一千零一十一"); TEST(11100, "一萬一千一百"); TEST(11101, "一萬一千一百零一"); TEST(11110, "一萬一千一百一十"); TEST(11111, "一萬一千一百一十一"); TEST(100000, "十萬"); TEST(100001, "十萬零一"); TEST(110000, "十一萬"); TEST(1000000, "一百萬"); TEST(1010000, "一百零一萬"); TEST(10000000, "一千萬"); TEST(10010000, "一千零一萬"); TEST(99999999, "九千九百九十九萬九千九百九十九"); TEST(100000000, "一億"); TEST(100000001, "一億零一"); TEST(110000000, "一億一千萬"); TEST(101000000, "一億零一百萬"); TEST(110100000, "一億一千零一十萬"); TEST(110010000, "一億一千零一萬"); TEST(101010000, "一億零一百零一萬"); TEST(100010000, "一億零一萬"); TEST(999999999, "九億九千九百九十九萬九千九百九十九"); TEST(4294967295, "四十二億九千四百九十六萬七千二百九十五"); }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define LST_MAX 127 typedef enum{FALSE = 0, TRUE = 1} BOOL; typedef struct { int lst[LST_MAX]; int len; } RESULT; typedef struct { unsigned long left; int mark; BOOL append0; unsigned long right; } ANALYSE_RESULT; typedef struct { unsigned long rank; int mark; } RANKS; enum {TEN = 10, HUNDRED = 11, THOUSAND = 12, TEN_THOUSEND = 13, HUNDRED_MILLION = 14}; static char *STR[] = {"零", "一", "二", "三", "四", "五", "六","七", "八", "九", "十", "百", "千", "萬", "億"}; static RANKS s_ranks[] = { {100000000, HUNDRED_MILLION}, {10000, TEN_THOUSEND}, {1000, THOUSAND}, {100, HUNDRED}, {10, TEN}, }; static int s_ranksLen = sizeof(s_ranks) / sizeof(RANKS); static BOOL CheckIfAppend0(int remain, int rank) { return (remain > 0 && remain < (rank / 10)) ? TRUE : FALSE; } static ANALYSE_RESULT Analyse(unsigned long n) { ANALYSE_RESULT result = {0}; int i = 0; for (i = 0; i < s_ranksLen; i++) { if (n >= s_ranks[i].rank) { result.left = n / s_ranks[i].rank; result.mark = s_ranks[i].mark; result.right = n % s_ranks[i].rank; result.append0 = CheckIfAppend0(result.right, s_ranks[i].rank); break; } } return result; } static RESULT Append(unsigned long n, RESULT result_in) { RESULT result = result_in; if (result.len < (sizeof(result.lst) / sizeof(result.lst[0]))) { result.lst[result.len] = n; result.len ++; } else { assert(0); } return result; } static RESULT TransN(unsigned long n, RESULT result_in) { RESULT result = result_in; if (n >= 10) { ANALYSE_RESULT ret = Analyse(n); result = TransN(ret.left, result); result = Append(ret.mark, result); if (ret.append0) result = Append(0, result); result = TransN(ret.right, result); } else if (n > 0) { result = Append(n, result); } return result; } static RESULT Trans(unsigned long n) { RESULT result = {{0}}; if (n == 0) { result = Append(0, result); } else { result = TransN(n, result); } return result; } static BOOL NeedSkip1(RESULT result) { return (result.len >= 2 && result.lst[0] == 1 && result.lst[1] == TEN) ? TRUE : FALSE; } static void Output(RESULT result_in, char *out, size_t outMaxSize) { char * p = out; int i = 0; if (NeedSkip1(result_in)) i++; /*根據用例需求或習慣確定是否要將"一十""一十二"等前面的"一"字去掉*/ while(i < result_in.len) { p += snprintf(p, outMaxSize - strlen(out), "%s", STR[result_in.lst[i]]); i++; } } static void ToChinese(unsigned long n, char *out, size_t outMaxSize) { /*靜態函式看作內部函式,不用進行有效性判斷,可以進行有效性測試,如*/ assert(out != NULL); assert(outMaxSize > strlen(STR[0])); assert(out[0] == '\0'); Output(Trans(n), out, outMaxSize); } char* ConvertToChinese(unsigned long n) { static char out[128];/*偷懶一下,引入不可重入問題, 可以考慮malloc或增加函式變數引入外部儲存*/ memset(out, 0, sizeof(out)); ToChinese(n, out, sizeof(out)); return out; } int main(int argc, char *argv[]) { #define TEST(IN, EXP) assert(strcmp(ConvertToChinese(IN), (EXP)) == 0) TEST(0, "零"); TEST(1, "一"); TEST(2, "二"); TEST(3, "三"); TEST(4, "四"); TEST(5, "五"); TEST(6, "六"); TEST(7, "七"); TEST(8, "八"); TEST(9, "九"); TEST(10, "十"); TEST(11, "十一"); TEST(20, "二十"); TEST(99, "九十九"); TEST(100, "一百"); TEST(101, "一百零一"); TEST(110, "一百一十"); TEST(111, "一百一十一"); TEST(1000, "一千"); TEST(1001, "一千零一"); TEST(1010, "一千零一十"); TEST(1011, "一千零一十一"); TEST(1100, "一千一百"); TEST(1101, "一千一百零一"); TEST(1110, "一千一百一十"); TEST(1111, "一千一百一十一"); TEST(10000, "一萬"); TEST(10001, "一萬零一"); TEST(10010, "一萬零一十"); TEST(10011, "一萬零一十一"); TEST(10100, "一萬零一百"); TEST(10101, "一萬零一百零一"); TEST(10110, "一萬零一百一十"); TEST(10111, "一萬零一百一十一"); TEST(11000, "一萬一千"); TEST(11001, "一萬一千零一"); TEST(11010, "一萬一千零一十"); TEST(11011, "一萬一千零一十一"); TEST(11100, "一萬一千一百"); TEST(11101, "一萬一千一百零一"); TEST(11110, "一萬一千一百一十"); TEST(11111, "一萬一千一百一十一"); TEST(100000, "十萬"); TEST(100001, "十萬零一"); TEST(110000, "十一萬"); TEST(1000000, "一百萬"); TEST(1010000, "一百零一萬"); TEST(10000000, "一千萬"); TEST(10010000, "一千零一萬"); TEST(99999999, "九千九百九十九萬九千九百九十九"); TEST(100000000, "一億"); TEST(100000001, "一億零一"); TEST(110000000, "一億一千萬"); TEST(101000000, "一億零一百萬"); TEST(110100000, "一億一千零一十萬"); TEST(110010000, "一億一千零一萬"); TEST(101010000, "一億零一百零一萬"); TEST(100010000, "一億零一萬"); TEST(1000000001, "十億零一"); TEST(1000000010, "十億零一十"); TEST(1000000100, "十億零一百"); TEST(1000001000, "十億零一千"); TEST(1000010000, "十億零一萬"); TEST(999999999, "九億九千九百九十九萬九千九百九十九"); TEST(4294967295, "四十二億九千四百九十六萬七千二百九十五"); system("PAUSE"); return 0; }
數字轉中文
char * ConvertToChinese(unsigned long);
比如:101輸出一百零一
測試用例:
#define TEST(IN, EXP) assert(strcmp(ConvertToChinese(IN), EXP) == 0)
TEST(0, "零");
TEST(1, "一");
TEST(2, "二");
TEST(3, "三");
TEST(4, "四");
TEST(5, "五");
TEST(6, "六");
TEST(7, "七");
TEST(8, "八");
TEST(9, "九");
TEST(10, "十");
TEST(11, "十一");
TEST(20, "二十");
TEST(99, "九十九");
TEST(100, "一百");
TEST(101, "一百零一");
TEST(110, "一百一十");
TEST(111, "一百一十一");
TEST(1000, "一千");
TEST(1001, "一千零一");
TEST(1010, "一千零一十");
TEST(1011, "一千零一十一");
TEST(1100, "一千一百");
TEST(1101, "一千一百零一");
TEST(1110, "一千一百一十");
TEST(1111, "一千一百一十一");
TEST(10000, "一萬");
TEST(10001, "一萬零一");
TEST(10010, "一萬零一十");
TEST(10011, "一萬零一十一");
TEST(10100, "一萬零一百");
TEST(10101, "一萬零一百零一");
TEST(10110, "一萬零一百一十");
TEST(10111, "一萬零一百一十一");
TEST(11000, "一萬一千");
TEST(11001, "一萬一千零一");
TEST(11010, "一萬一千零一十");
TEST(11011, "一萬一千零一十一");
TEST(11100, "一萬一千一百");
TEST(11101, "一萬一千一百零一");
TEST(11110, "一萬一千一百一十");
TEST(11111, "一萬一千一百一十一");
TEST(100000, "十萬");
TEST(100001, "十萬零一");
TEST(110000, "十一萬");
TEST(1000000, "一百萬");
TEST(1010000, "一百零一萬");
TEST(10000000, "一千萬");
TEST(10010000, "一千零一萬");
TEST(99999999, "九千九百九十九萬九千九百九十九");
TEST(100000000, "一億");
TEST(100000001, "一億零一");
TEST(110000000, "一億一千萬");
TEST(101000000, "一億零一百萬");
TEST(110100000, "一億一千零一十萬");
TEST(110010000, "一億一千零一萬");
TEST(101010000, "一億零一百零一萬");
TEST(100010000, "一億零一萬");
TEST(999999999, "九億九千九百九十九萬九千九百九十九");
TEST(4294967295, "四十二億九千四百九十六萬七千二百九十五");