Output: 壹拾贰万叁仟肆佰伍拾陆元壹分
Accurate the result to the cent with (四舍五入,我不记得怎么表达的了,反正能看懂)你的题目可以参考如下代码(如有帮助,望采纳!谢谢! 点击我这个回答右上方的【采纳】按钮)
//=================================================================
// 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;
}