c++实现人命币大小写转换


5月7号修改:
针对5月6号出现的问题二对程序做了改进。主要体现在:
当我输入85.99,程序执行到处理小数部分时,计算机实际上存储的数字为0.98999999999999488;当我输入5.99,程序执行到处理小数部分时,计算机实际上存储的数字为0.99000000000000021,但是能输出正确结果。虽然知道用二进制数表示小数并不能做到完全相等,但似乎如果误差小于一个特定的值,计算机还是能输出我们想要的结果。于是我加了这么一个判断,运算结果是我们想要的。
题外话:很奇怪的一件事,在这个程序中,小数部分的误差与前面整数大小成正比例;而且在while循环里,误差越来越大。

if(abs(1 - dMoney)>0.0000000000000001 && abs(1 - dMoney)<=0.001){
    mMoney ++;
}

5月6号修改:
在做黑盒测试时,发现了一些问题:
1):当我输入.00时,虽然含有小数,但应该输出错误信息,实际输出整;但当我输入0.00时,能识别输入信息不能为0;
2):当我输入85.99时,输出八十五元九角八分
3):当我输入0.85时,提示输入” 请输入具体的数值,且不能为零 “的错误
针对第一、三问题,我修改了isAvailable()函数中一些判断逻辑,使其能处理0开头的非零数字;针对第二个问题,暂时还没有想到更好的解决办法,不知你们有没有一些想法


问题是简单的,但要完全考虑到所有的情况还是有点难度的,这是我写的代码,由于水平有限,没有考虑到情况欢迎留言讨论。
首先是判断输入数据是否是有效输入,其中high和low是全局变量,分别表示整数部分的位数以及小数部分的位数

/*
此函数用于判断输入的从键盘输入的数据是否有效
当输入数据大于千亿、小数点后数字多于2个、或是含有字母时,无效输入
*/
bool isAvailable(std::string inputMoney){
    std::string::iterator pInputMoney = inputMoney.begin();
    //判断是否读到了小数点
    bool isMeetDot = false;
    bool firstMeetDot = true;

    if (atof(inputMoney.c_str()) == 0){
        std::cout<<"请输入具体的数值,且不能为零"<<std::endl;
        return false;
    }
    //遍历输入的数据
    for( ; pInputMoney < inputMoney.end() ; pInputMoney ++){
        if (isMeetDot){
            low ++;
        }
        if (*pInputMoney > '9' || *pInputMoney < '0'){
            if (*pInputMoney == '.'){
                if (firstMeetDot){
                    isMeetDot = true;
                    firstMeetDot = false;
                }else{
                    std::cout<<"小数点只能有一个,不能有多个"<<std::endl;
                    return false;
                }
            }else{
                std::cout<<"请输入数字,不能输入字符"<<std::endl;
                return false;
            }
        }
        if (!isMeetDot){
            high ++;
        }
    }
    //小数部分的位数,不能超过2,否则当作非法输入
    if (low > 2){
        std::cout<<"小数点后面至多两位"<<std::endl;
        return false;
    }
    //整数部分的位数,不能超过12,否则当作非法输入
    if (high > 12){
        std::cout<<"输入数据过大,目前只支持仟亿"<<std::endl;
    }
    return true;
}

然后需要将string型数据转换为double数据

/*
string型数据转化为double型
*/
void stringTranslate2Double(string inputStr , double &inputDouble){
    inputDouble = atof(const_cast<const char*>(inputStr.c_str()));
}

然后是处理double型数据,这是main函数

/*
有效测试数据:805.08 、 8005.80 、 85.00 、 85 、 8500 、 85.85 、 8050
无效测试数据:85000000000000 、 85.001 、 85..85 、 85.a8
*/
int main(){
    std::string sMoney;
    double dMoney;
    const std::string NUM[10] = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    const std::string UNIT[] = {"分","角","元","拾","佰","仟","万","拾","佰","仟","亿","拾","佰""仟"};
    for (;;){
        high = 0 ;
        low = 0;
        int mMoney = 0;
        bool FrontNumberIsZero = false;
        std::cout<<"请输入待转换的数值:"<<std::endl;
        std::cin>>sMoney;
        //退出循环
        if (sMoney == "exit"){
            break;
        }
        if(isAvailable(sMoney)){
            std::cout<<"转化后为:\t";
            stringTranslate2Double(sMoney,dMoney);
            //std::cout<<dMoney<<std::endl;
            std::cout<<"人名币:";
            //处理整数部分
            while (high != 0){
                mMoney = dMoney / (pow(10,high-1));
                dMoney = dMoney - (pow(10,high-1)) * mMoney;
                if (mMoney == 0){
                    FrontNumberIsZero = true;
                    switch (high){
                    case 9:
                        std::cout<<UNIT[high+1];
                        //FrontNumberIsZero = false;
                        break;
                    case 5:
                        std::cout<<UNIT[high+1];
                        //FrontNumberIsZero = false;
                        break;
                    case 1:
                        std::cout<<UNIT[high+1];
                        //FrontNumberIsZero = false;
                        break;
                    default:
                        break;
                    }
                }else{
                    if (FrontNumberIsZero){
                        std::cout<<NUM[0];
                    }
                    FrontNumberIsZero = false;
                    std::cout<<NUM[mMoney]<<UNIT[high+1];
                }
                if (high == 1 && low == 0){
                    std::cout<<"整";
                }
                high--;
            }
            //处理小数部分,类似于对整数的处理
            while (low != 0){
                mMoney = dMoney * 10;
                dMoney = dMoney * 10 - mMoney;
                //因为计算机表示小数并不是精确的表示,所以可能会存在表示上的误差
                //这个if循环是简单的处理这个误差,但不能完全的根除,这里只是提供一个经验值
                if(abs(1 - dMoney) > 0.0000000000000001 && abs(1 - dMoney) <= 0.001){
                    mMoney ++;
                }
                if(mMoney == 0 ){
                    if (low == 1){
                        if (FrontNumberIsZero){
                            std::cout<<"整";
                        }
                    }
                    FrontNumberIsZero = true;
                }else{
                    if (FrontNumberIsZero){
                        std::cout<<NUM[0];
                    }
                    std::cout<<NUM[mMoney]<<UNIT[low-1];
                    FrontNumberIsZero = false;
                }
                low --;
            }
            std::cout<<std::endl;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值