人民币数字大写转换(C++)

软测实验-人民币数字大写转换


具体需求如下:

        1)中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整(正)等字样。

        2)中文大写金额数字到"元"为止的,在"元"之后,应写"整"(或"正")字,在"角"之后,可以不写"整"(或"正")字。

        3)中文大写金额数字前应标明"人民币"字样,大写金额数字有"分"的,"分"后面不写"整"(或"正")字。

        4)大写金额数字应紧接"人民币"字样填写,不得留有空白。

        5)阿拉伯数字小写金额数字中有"0"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。

举例如下:

1、阿拉伯数字中间有"0"时,中文大写要写"零"字,如¥1409.50,应写成:人民币壹仟肆佰零玖元伍角。

2、阿拉伯数字中间连续有几个"0"时,中文大写金额中间只写一个"零"字,如¥6007.14,应写成:人民币陆仟零柒元壹角肆分。

3、阿拉伯金额数字万位和元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写金额中只写一个零字,也可以不写"零"字。如¥1680.32,应写成:人民币壹仟陆佰捌拾元叁角贰分,又如¥107000.53,应写成:人民币壹拾万零柒仟元伍角叁分。

4、阿拉伯金额数字角位是"0",而分位不是"0"时,中文大写金额"元"后面应写"零"字。如¥16409.02,应写成人民币:壹万陆仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元零肆分。


注:

  • 代码测试时暂时发现一下bug(不全):    
              • 1. 输入0.00时输出结果不对;

  • 转载请表明出处!

#include <iostream>
#include <sstream>
#include <string>
#include <stack>
/*
 *
 *  " 1)中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整(正)等字样。"
    " 2)中文大写金额数字到\"元\"为止的,在\"元\"之后,应写\"整\"(或\"正\")字,在\"角\"之后,可以不写\"整\"(或\"正\")字。"
    " 3)中文大写金额数字前应标明\"人民币\"字样,大写金额数字有\"分\"的,\"分\"后面不写\"整\"(或\"正\")字。"
    " 4)大写金额数字应紧接\"人民币\"字样填写,不得留有空白。"
    " 5)阿拉伯数字小写金额数字中有\"0\"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。"
 *
 * 注:
 *      1. 私有成员变量的命名规则:名称后加上一个下划线
 *      2.
 * */

using namespace std;

class Num2Uper
{
public:
    Num2Uper(const string &num)
    {
        /*此处应该检查num的值是否合法。
         * 如:
         *      1- 小于0
         *      2- 小数不合法
         *      3- 数字本身不合法
         *      4- 小数点是非法字符等
         * */
        
        //if (num.size()-)
        
        this->setNum(num);
    }
    
    Num2Uper()
    {
        this->num_ = nullptr;
        this->word_ = nullptr;
        
    }
    
    const string &getWord() const
    {
        return word_;
    }
    
    void setWord(const string &word)
    {
        Num2Uper::word_ = word;
    }
    
    const string &getNum() const
    {
        return num_;
    }
    
    void setNum(const string &num)
    {
        Num2Uper::num_ = num;
    }
    
    virtual ~Num2Uper()
    {
    
    }


private:
    string word_;
    string num_;
//    static  string touper_[10]={"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
//    static  string unit_[15] = { "万", "仟", "佰", "拾", "亿", "仟", "佰", "拾", "万", "仟", "佰", "拾","元", "角", "分"};
    
    static string digits_[10];
    static  string unit_1[13];

    static  string unit_2[2];
   

public:
    
    void transform()
    {
        string part_int;
        string part_dec;
        int point_pos = int(this->getNum().find('.'));
//        cout<<"point_pos = "<<point_pos<<endl;
        if (point_pos ==-1)
        {
            part_int = this->num_;
        }
        else
        {
            part_int = num_.substr(0,point_pos);
            part_dec = num_.substr(point_pos+1);
        }
        
        int part_int_size = part_int.size();
//        cout<<"part_int_size = "<<part_int_size<<endl;
        bool zero_flag = true; // flase表示有0
        bool prev_zero_flag = false; // false表示0位之前有非零数
        stack<string> result;
    
        for (int i = 0; i < part_int_size; ++i)
        {
//            cout<<"i = "<<i<<endl;
            int tmp = int(part_int[part_int_size-i-1])- 48;
            if (i%4 == 0)
            {
                if (tmp == 0)
                {

                    if (!zero_flag&&prev_zero_flag)
                    {
                        result.push(digits_[0]);
                    }
                    result.push(unit_1[i]);
                    zero_flag = false;
                    prev_zero_flag = false;
                }
                else
                {
                    //101
                    if (!zero_flag && prev_zero_flag)
                    {
                        result.push(digits_[0]);
                    }
                    result.push(unit_1[i]);
                    result.push(digits_[tmp]);
    
                    zero_flag = true;
                    prev_zero_flag = true;
                }
                
            }
            else
            {
                if (tmp == 0)
                {
                    zero_flag = false;
                    continue;
                }
                else
                {
                    if (prev_zero_flag&&!zero_flag)
                    {
//                        result.push(digits_[0]);
                        result.push(digits_[0]);
                    }
                    result.push(unit_1[i]);
                    result.push(digits_[tmp]);
                    prev_zero_flag = true;
                    zero_flag = true;
                }
            }
            
        }
        string tmp;
        while (!result.empty())
        {
            tmp = result.top();
            result.pop();
            if (tmp=="亿" &&  result.top() == "万")
            {
                result.pop();
            }
            
           word_.append(tmp);
//            result.pop();
        }
        if (point_pos == -1 )
        {
            word_.append("元整");
        }
        else
        {
            word_.append("元");
            for (int i = 0; i < part_dec.size(); ++i)
            {
                word_.append(digits_[int(part_dec[i])-48]);
                word_.append(unit_2[i]);
            }
            
        }
    }
    
    string num2uper(int n)
    {
        if (n<0||n>9)
        {
            cerr<<"Wrong Number!"<<endl;
        }
        else
        {
            return this->digits_[n];
        }
    }
    
};

string Num2Uper::digits_[10]={"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
string Num2Uper::unit_1[13] = {"", "拾", "佰", "千", "万", "拾", "佰", "千", "亿", "拾", "佰", "千","万"};
string Num2Uper::unit_2[2] = {"角", "分"};



int main()
{
    string str;
    while(1)
    {
        cout<<"请输入金额:";
        cin>>str;
        if (str == "-1")
            break;
        Num2Uper num = Num2Uper(str);
        num.transform();
        cout<<"人民币"<<num.getWord()<<endl;
    }
    return 0;
}

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值