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

  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

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

//=================================================================
// 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