要求和内容
编写控制台模式的程序,接收用户输入的整数,然后将其转换为中文大写金
额的形式。 例如:
输入: 1024
输出: 壹仟零贰拾肆
要求如下:
1)输入输出必须使用 cin、cout。
2)要求每个源文件仅包含单一功能模块。
3) 先设计测试用的例子,并在 test.cpp 中实现,然后实现代码。
4) 在实现上述要求的基础上,修改代码,使其可以转换小数形式的数据,例如输入 3.12时,转换为叁元壹角贰分。
5) 在实现上述要求的基础上,修改代码,使其在输入错误时,给出错误提示,并说明错误出现的位置。
calc.cpp
#include <iostream> #include <sstream> #include <string> #include <stack> //将string转换成wstring #include "calc.h" using namespace std; void Num2Uper::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::digits_[10] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; string Num2Uper::unit_1[13] = { "", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟","万" }; string Num2Uper::unit_2[2] = { "角", "分" };
calc.h
#ifndef _CALC__H #define _CALC__H #include <iostream> #include <sstream> #include <string> #include <stack> #include <locale> #include <codecvt> #include <comdef.h> 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(); }; wstring string2wstring(string str); #endif // !_CALC__H
chinesetonum.cpp
#include<string> #include<iostream> #include<map> #include<vector> #include<algorithm> #include <sstream> #include <stack> #include "chinesetonum.h" using namespace std; /*wstring,使用的是wchar_t类型,这是宽字符,用于满足非ASCII字符的要求,例如Unicode编码,中文,日文,韩文什么的。 */ wstring wsNum = { L"零壹贰叁肆伍陆柒捌玖" }; wstring wsUnit = { L"拾佰仟万亿" }; map<wchar_t, long long> m; //数字:零:0 一:1 ... //单位: 十:10 百:100 ... //建立wchar_t型到long型的映射 void buildMap() { for (int i = 0; i < wsNum.size(); ++i) { // printf("wsNum[%d] = %s\r\n", i,wsNum[i]); m[wsNum[i]] = i; } int unit = 1; for (int i = 0; i < wsUnit.size(); ++i) { if (i == wsUnit.size() - 1) { unit *= 1e4; } else { unit *= 10; } m[wsUnit[i]] = unit; } } long long changeChinese2Int(wstring s) { reverse(s.begin(), s.end()); long long ret = 0; long long curUnit = 1; for (auto c : s) {//输出一个数组的全部元素 int n = m[c]; if (n <= 9) { ret += n * curUnit; } else { if (n > curUnit) { curUnit = n; } else { curUnit *= n; } } } if (m[s.back()] > 9) { ret += curUnit; //针对不规范的输入,比如输入"十八",而不是"一十八" } return ret; }
chinesetonum.h
#ifndef _CHINESETONUM__H #define _CHINESETONUM__H #include<string> #include<iostream> #include<map> #include<vector> #include<algorithm> #include <sstream> #include <stack> using namespace std; class chinese_to_num { public: void buildMap(); long long changeChinese2Int(wstring s); void chinese_to_num_test(void); }; void buildMap(); long long changeChinese2Int(wstring s); #endif // !_CHINESETONUM__H
test.cpp
#include<string> #include<iostream> #include<map> #include<vector> #include<algorithm> #include <sstream> #include <stack> #include "chinesetonum.h" #include "test.h" #include "calc.h" using namespace std; void test0(void) { std::string s = std::to_string(42); cout << s << endl; if (s == "-1") return; Num2Uper num = Num2Uper(s); num.transform(); cout << "人民币" << num.getWord() << endl; } void test1(void) { std::string s = std::to_string(10009); cout << s << endl; if (s == "-1") return; Num2Uper num = Num2Uper(s); num.transform(); cout << "人民币" << num.getWord() << endl; } void test2(void) { std::string s = std::to_string(10.98); cout << s << endl; if (s == "-1") return; Num2Uper num = Num2Uper(s); num.transform(); cout << "人民币" << num.getWord() << endl; } void test3(void) { std::string s = std::to_string(987654321); cout << s << endl; if (s == "-1") return; Num2Uper num = Num2Uper(s); num.transform(); cout << "人民币" << num.getWord() << endl; } void test4(void) { std::string s = std::to_string(4100200); cout << s << endl; if (s == "-1") return; Num2Uper num = Num2Uper(s); num.transform(); cout << "人民币" << num.getWord() << endl; } void test(void) { test0(); test1(); test2(); test3(); test4(); //chinese_to_num_test(); } void chinese_to_num_test(void) { buildMap(); vector<wstring> v_test = { L"捌", L"壹拾", L"拾捌", L"捌拾", L"捌拾贰", L"壹佰", L"捌佰零捌", L"壹仟零贰万零玖拾", L"贰仟亿零壹佰零壹万零贰佰", L"贰佰叁拾肆", }; for (int i = 0; i < v_test.size(); ++i) { wcout.imbue(locale("chs")); wcout << v_test[i] << endl; long long ret = changeChinese2Int(v_test[i]); cout << ret << endl; } }
test.h
#ifndef _TEST__H #define _TEST__H void test(); void chinese_to_num_test(void); #endif // !_TEST__H
main.cpp
#include <iostream> #include <sstream> #include <string> #include <stack> #include <Windows.h> #include <locale> #include "calc.h" #include "test.h" #include "chinesetonum.h" using namespace std; //wstring wsNum = //{ L"零壹贰叁肆伍陆柒捌玖" }; //wstring wsUnit = { L"拾佰仟万亿" }; int main() { cout << "数字转中文大写测试:" << endl; test(); cout << "中文大写转数字测试:" << endl; chinese_to_num_test(); cout << "\r\n" << endl; string str; while (1) { cout << "请输入数字金额:"; cin >> str; if (str == "-1") break; Num2Uper num = Num2Uper(str); num.transform(); cout << "人民币" << num.getWord() << endl; wcin.imbue(locale("chs")); wcout.imbue(locale("chs")); wstring str; cout << "请输入中文金额:"; wcin >> str; long long ret = changeChinese2Int(str); cout << ret << endl; } return 0; }