编程题
仓库戳这里
这次的主要改进
优化了一下代码的架构,刚开始的函数全部丢在一个cpp文件中进行编写,这样后期看起来显得很乱,于是这一次尝试用分文件编写来实现代码
把函数的声明写在头文件,把实现写在另外一个cpp文件中,这样整个主函数部分看起来清爽了很多,尽可能的将功能进行模块化
这是汉语言计算头文件.h的代码
#pragma once
#include <iostream>
#include <string>
using namespace std;
int find(string zhao);//将汉字转化为数字
void find(int num);//将数字转化为汉字
int find(const string& pipei, int);//用于分析语句的意思并返回值
//find函数重载
void dingyi(int& money, string& wen);//初始化钱包
void jianfa(int& money, string& wen);//减法操作
void jiafa(int& money, string& wen);//加法操作
//功能函数
const char shu[11][3] = { "零","一", "二","三","四","五","六","七","八","九","十" };
//对基本的汉字进行定义
这次的函数实现部分增加了可以运算数字的范围,增加了负数,并将数字转汉字扩展到了-999~+999
在修改过程中还遇到了字符串深浅拷贝的问题,用引用的时候没有注意,后来为了防止自己不小心去修改原字符串,使用了const string &
这是函数实现部分
#include "汉语言计算头文件.h"
//汉字转化为数字
int find(string zhao) {
int len = zhao.length();
int sum = 0;
int i, flag = 0,fu = 1;
string yuan;
//针对负数的情况
if (zhao.compare(0, 2, "负") == 0) {
fu = 0;
len -= 2;
zhao = zhao.substr(2, len);
}
//三个汉字
if (len == 6) {
for (i = 0; i < 11; i++) {
if (zhao.compare(0, 2, shu[i]) == 0) {
sum += 10 * i;
flag = 1;
break;
}
if (flag == 0 && i == 10) return -1;
}
flag = 0;
for (i = 0; i < 11; i++) {
if (zhao.compare(4, 2, shu[i]) == 0) {
sum += i;
flag = 1;
break;
}
if (flag == 0 && i == 10) return -1;
}
}
//两个汉字
else if (len == 4) {
sum = 1;
for (i = 0; i < 11; i++) {
if (zhao.compare(0, 2, shu[i]) == 0) {
flag = 1;
break;
}
}
if (i == 10) {
for (i = 0; i < 11; i++) {
if (zhao.compare(2, 2, shu[i]) == 0) {
flag = 1;
break;
}
}
sum = 10 + i;
}
else if (i < 10 && i>0) {
sum = i * 10;
}
else if (flag == 0 && i == 10) return -1;
}
//一个汉字
else if (len == 2) {
for (i = 0; i < 11; i++) {
if (zhao.compare(0, 2, shu[i]) == 0) {
sum += i;
flag = 1;
break;
}
if (flag == 0 && i == 10) return -1;
}
}
if (fu == 0) {
sum *= -1;
}
return sum;
}
//数字转化为汉字
void find(int num) {
if (num < 0) {
cout << "负";
num *= -1;
}
if (num <= 10 && num >= 0) {
cout << shu[num] << endl;
}
else if (num > 10 && num < 100) {
cout << shu[num / 10] << "十" << shu[num % 10] << endl;
}
else if (num >= 100 && num <= 999) {
cout << shu[num / 100] << "百";
if (num / 10 % 10 != 0) {
cout << shu[num / 10 % 10] << "十";
}
else if (num % 10 != 0)cout << "零";
if (num % 10 != 0) {
cout << shu[num % 10];
}
cout << endl;
}
}
//寻找匹配的字符串
int find(const string& pipei, int) {
string kankan = "看看 钱包";
string yuan = "整数 钱包 等于";
string jia = "钱包 增加";
string jian = "钱包 减少";
string temp;
//定义钱包初始数额
if (pipei.compare(0, 13, yuan, 0, 13) == 0) return 1;
//看看钱包的余额
else if (pipei.compare(0, 9, kankan, 0, 9) == 0) return 2;
//对余额进行加法操作
else if (pipei.compare(0, 9, jia, 0, 9) == 0) return 3;
//对余额进行减法操作
else if (pipei.compare(0, 9, jian, 0, 9) == 0) return 4;
//异常处理
else return -1;
}
//定义钱包初始数额
void dingyi(int& money, string& wen) {
int len = wen.length();
string temp = wen.substr(15, len);
if (find(temp) != -1) {
money = find(temp);
}
else {
printf("非法输入
");//异常处理
}
}
//对钱包做加法运算
void jianfa(int& money, string& wen) {
//printf("4");
int len = wen.length();
string temp = wen.substr(10, len);
if (find(temp) != -1) {
money -= find(temp);
}
else {
printf("非法输入
");//异常处理
}
}
//对钱包做减法运算
void jiafa(int& money, string& wen) {
//printf("3");
int len = wen.length();
string temp = wen.substr(10, len);
if (find(temp) != -1) {
money += find(temp);
}
else {
printf("非法输入
");//异常处理
}
}
通过分文件编写就可以使主函数部分看起来清爽一些,通过函数调用的返回值可以判断需要执行的是哪一个操作
这是修改后的主函数部分
#include <fstream>
#include "汉语言计算头文件.h"
int main() {
int money = 0;
string a;
ifstream ifs;
ifs.open("test01.txt", ios::in);
while (getline(ifs,a)) {//通过返回值类型判断要执行哪个操作
switch (find(a, 1)) {
case 1://定义钱包初始数额
dingyi(money, a); break;
case 2://看看钱包还有多少数额
find(money); break;
case 3://对钱包做加法运算
jiafa(money, a); break;
case 4://对钱包做减法运算
jianfa(money, a); break;
default://异常状况
cout << "非法输入" << endl;
}
if (find(a, 1) == 2) break;
else continue;
}
ifs.close();
return 0;
}
反思
自己经常犯的错误是,在修改函数定义后忘记去头文件那边修改声明,导致连接不成功。
在考虑数的范围的时候,数字转化为汉字相对比较好写,而汉字转化为数字则需要分比较多的情况讨论。