lhdashuai 2021-07-11 02:05 采纳率: 0%
浏览 18

一道简单的读取题,感觉不太好做出来

  1. Please input a float and transform it into Chinese (written as banknote)
    For example: input 123456.01
            Output: 壹拾贰万叁仟肆佰伍拾陆元壹分
    
    Accurate the result to the cent with (四舍五入,我不记得怎么表达的了,反正能看懂)
    Please write a program which can apply to as large a number as possible
  • 写回答

1条回答 默认 最新

  • 关注

    你的题目可以参考如下代码(如有帮助,望采纳!谢谢! 点击我这个回答右上方的【采纳】按钮)

    //=================================================================
    // CPSTR: Copyright (c) 2020 By Abodu, All Rights Reserved.
    // FNAME: arabToChinese.c
    // AUTHR: abodu,abodu@qq.com
    // CREAT: 2020-06-14 14:56:23
    // ENCOD: UTF-8 Without BOM
    // VERNO: 1.0.3
    // LUPTS: 2021-06-03 17:25:04
    //=================================================================
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /**
     * 删除字符串中所有的目标字符 target
     */
    void removeCommaAll(char *str, char target);
    /**
     * 阿拉伯数字表示的金额串转换成中文大写金额
     * 转换成功,则输出转换后的大写金额
     * 转换失败,则返回NULL
     */
    char *arabToChinese(char *dest, char *src);
    
    //====STEP0:准备阶段 ==============================
    
    #define JINER_MAX_SIZE 30
    #define CNFEE_MAX_SIZE 300
    //定义FSM(有限状态机)的状态
    enum FSM_Sole_t {
        BEGIN,   /**< 起始位 */
        MINUS,   /**< 负号位 */
        ZEROPRE, /**< 前缀零(格式 0.XX 或 -0.XX) */
        INTEGER, /**< 整数位 */
        DECIMAL, /**< 小数位 */
    };
    
    char *CHN_UNIT[] = {
        "整", "圆",              /**<*/
        "拾", "佰", "仟", "万",  /**<*/
        "拾", "佰", "仟", "亿",  /**<*/
        "拾", "佰", "仟", "兆",  /**<*/
        "拾", "佰", "仟", "京",  /**<*/
        "拾", "佰", "仟", "万京" /**<*/
    };
    char *CHN_NUMBER[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    char *CHN_ERRMSG[] = {
        "[OK]"
        "[ERR]格式错误,负号(-)出现在金额串的不正确位置处",
        "[ERR]格式错误,小数点(.)只能出现一次",
        "[ERR]格式错误,除-0.XX和0.XX外,不允许出现前置零(0XXX)",
        "[ERR]格式错误,输入的串内含有不属于十进制金额的其他字符",
    };
    
    int main(int argc, char *argv[])
    {
        char result[CNFEE_MAX_SIZE] = {0};
        char szInput[JINER_MAX_SIZE] = {0};
        int i = 1;
        char *p = NULL;
    
        fprintf(stderr, "---- 阿拉伯数字转化成中文金额字符串(小数部分仅保留到分) ---- \n");
        do {
            result[0] = 0, szInput[0] = 0;
            if (argc == 1) {
                //后面没有参数,需要手动输入一个小写金额
                printf("请输入(阿拉伯数字表示的)小写金额:>");
                scanf("%s", szInput);
            } else {
                sprintf(szInput, "%s", argv[i++]);
            }
    
            removeCommaAll(szInput, ',');
            printf("%s --> %s\n", szInput, arabToChinese(result, szInput));
        } while (i < argc);
        return 0;
    }
    
    void removeCommaAll(char *str, char c)
    {
        int i = 0, j = 0;
        while (str[i]) {
            if (str[i] != c) {
                str[j++] = str[i];
            }
            i++;
        }
        str[j] = '\0';
    }
    char *arabToChinese(char *szOutput, char *aInput)
    {
        enum FSM_Sole_t state = BEGIN;
        int errIndex = -1;
        typedef char *pos_t;
    
        /**<
         * 下面的变量定义初始化成NULL至关重要
         * 关系着某些位置是否存在,若是一直是NULL则表示某个位置是不存在的
         **/
        pos_t pDecBgn = NULL, pMinus = NULL;
        //将it 与 pIntBgn 同时指向输入的金额串的开头
        pos_t szInput = strdup(aInput);
        pos_t pIntBgn = szInput;
        pos_t it = szInput; //(it是遍历指针,iterator的缩写)
    
        /**< PART1 ====使用状态机解析金额串,若是有格式错误 则会报错并返回 ==== */
        do {
            switch (*it) {
                case '-': /**< CLASS0: 当前字符是负号(-) */
                    if (BEGIN != state) {
                        /**< 说明在非起始位又遇见了负号,格式错误序号设置成1 */
                        return CHN_ERRMSG[1];
                    } else {
                        /**< 负号在最开头才算是合法的 */
                        pMinus = it;
                        pIntBgn++;     /**< 将整数部分的开头后移一位(以保证整数部分只包含数字) */
                        state = MINUS; /**< 状态更新为 MINUS */
                    }
                    break;
                case '.': /**< CLASS2: 当前字符是小数点 */
                    if (DECIMAL == state) {
                        /**< 已经在小数位状态, 再一次遇见小数点 */
                        return CHN_ERRMSG[1];
                    } else {
                        /**< 后面的一位就是小数部分的起始位置 */
                        pDecBgn = it + 1;
                        /**< 置为 \0 则保证整数部分结束了 */
                        *it = '\0';
    
                        /**< 负号位状态(-.XXX) 或 起始位状态(.XXX) 时 优化掉整数转换部分 */
                        if (MINUS == state || BEGIN == state) {
                            pIntBgn = NULL; //更新 pIntBgn 为 NULL
                        }
                        /**< 除非遇到格式错误提前退出,否则 状态会一直保持为 小数位状态 到输入串结束 */
                        state = DECIMAL;
                    }
                    break;
                case '0' ... '9': /**< CLASS1: 当前字符是数字符号 */
                    if (ZEROPRE == state) {
                        /**< 在处于有前缀0的状态下又碰见一个数字字符,表示格式有误 */
                        return CHN_ERRMSG[2];
                    } else if (it[0] == '0' && (MINUS == state || BEGIN == state)) {
                        /**< 当前状态为 负号位状态 或 起始位状态 并且 字符是 0 时, 置为状态转化为 前缀零 */
                        state = ZEROPRE;
                    } else { /**< 其他均转化为 数字符号状态 */
                        state = INTEGER;
                    }
                    break;
                default:
                    /**< CLASS2: 当前字符是除 负号,小数点,数字字符 之外的其他字符 */
                    return CHN_ERRMSG[3];
            }
    
            /**< it后移一位,为进行下一轮判断做准备 */
            it++;
        } while (*it); /**<当it到达szInput的末尾就退出循环 */
    
        /**<  PART2 ==== 进行转换 ==== */
    
        if (pMinus) {
            /**< 有负号 */
            strcat(szOutput, "负");
        }
    
        /**< ====转换整数部分 ==== */
        if (pIntBgn && pIntBgn[0] != '0') {
            /**< 有整数部分并且以非零开头才需要进行转换 */
            int kNum;
            pos_t kHZ = NULL;
            pos_t kDW = NULL;
            it = pIntBgn; //将it重置到整数部分的开头
            int kWeight = strlen(it);
            do {
                kNum = it[0] & 0xF; //<==> it[0] - '0', 输入的数字字符转换成对应的数字
                kDW = CHN_UNIT[kWeight], kHZ = CHN_NUMBER[kNum];
                if (kNum) {
                    if (kWeight % 4 == 1) {
                        strcat(szOutput, kHZ);
                    } else {
                        if (kWeight % 4 == 2 && kNum == 1) {
                            strcat(szOutput, kDW);
                        } else {
                            sprintf(szOutput, "%s%s%s", szOutput, kHZ, kDW);
                        }
                    }
                } else {
                    if ((kWeight % 4 != 1) && (it[1] != '0')) {
                        strcat(szOutput, kHZ);
                    }
                }
                //对可能需要添加的特殊单位进行判断
                if (kWeight % 4 == 1) {
                    if (0 != strncmp("000", it - 3, 3) || (it[1] == '\0')) {
                        strcat(szOutput, kDW);
                    }
                }
                // it每向后移一位,权位降一级
                it++, kWeight--;
            } while (*it);
        }
    
        /**< ====转换小数部分 ==== */
        if (
            /*没有小数部分*/
            pDecBgn == NULL || pDecBgn[0] == '\0' ||
            /*串的格式类似于 XX.0 或 XX.00 */
            (pDecBgn[0] == '0' && (pDecBgn[1] == '0' || pDecBgn[1] == '\0'))) {
            //直接打印"XX圆整"
            strcat(szOutput, CHN_UNIT[0]);
        } else { //至少有一位小数
            strcat(szOutput, CHN_NUMBER[pDecBgn[0] & 0xF]);
            if (pDecBgn[0] != '0') { //跳过'零角'的字样
                strcat(szOutput, "角");
            }
            if (pDecBgn[1] != '\0' && pDecBgn[1] != '0') { //跳过'零分'的字样
                sprintf(szOutput, "%s%s分", szOutput, CHN_NUMBER[pDecBgn[1] & 0xF]);
            }
        }
        return szOutput;
    }
    
    
    

    img

    评论

报告相同问题?

问题事件

  • 创建了问题 7月11日

悬赏问题

  • ¥60 如何批量获取json的url
  • ¥15 对法兰连接元件所承受的表面载荷等效转化为法兰开孔接触面上的等效表面载荷?
  • ¥15 comsol仿真压阻传感器
  • ¥15 Python线性规划函数optimize.linprog求解为整数
  • ¥15 llama3中文版微调
  • ¥15 pg数据库导入数据序列重复
  • ¥15 三分类机器学习模型可视化分析
  • ¥15 本地测试网站127.0.0.1 已拒绝连接,如何解决?(标签-ubuntu)
  • ¥50 Qt在release捕获异常并跟踪堆栈(有Demo,跑一下环境再回答)
  • ¥30 python,LLM 文本提炼