1. 程式人生 > >人民幣數字大寫轉換(C++)

人民幣數字大寫轉換(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;
}