这个作业属于哪个课程 | 2020年面向对象程序设计 |
---|---|
这个作业要求在哪里 | 面向对象程序设计寒假作业2 |
这个作业的目标 | 1.继续完成编程题 2.新建一个github仓库,并把作业推送到该仓库。 3.发布博客 |
作业正文 | https://www.cnblogs.com/ying-hua/p/12240862.html |
其他参考文献 | https://blog.csdn.net/xinjitmzy/article/details/78967204 http://xstarcd.github.io/wiki/windows/windows_cmd_summary_commands.html https://www.cnblogs.com/hugb/articles/7410325.html |
一、编程题优化
此次优化取消了穷举法,使代码更加简短
将定义、计算和看看模块写成了函数
完整代码(v2.0)
#include
#include
#include
#include
struct Var{ //定义结构体,将汉字和英文变量一一对应
int engv; //英文变量
char chi[20]; //汉字变量
};
struct Var var[100]={0,""};
void error() //错误输出
{
printf("你写错啦!!!\n");
}
int op_legal(char op[]) //操作合法性
{
int num_legal(char num2[]);
if(strcmp(op,"等于")==0||strcmp(op,"增加")==0||strcmp(op,"减少")==0||num_legal(op)==1)
return 0;
return 1;
}
int var_legal(char vari[]) //变量合法性
{
int i;
if(strcmp(vari,"整数")==0||strcmp(vari,"等于")==0||
strcmp(vari,"增加")==0||strcmp(vari,"减少")==0||strcmp(vari,"看看")==0)
return 0;
for(i=0;strlen(var[i].chi)!=0;i++)
if(strcmp(vari,var[i].chi)==0) //变量已被定义过
return 0;
return 1;
}
int num_legal(char num2[]) //数字合法性
{
int i;
char num[10],chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
strcpy(num,num2);
if(strlen(num)==2){
for(i=0;i<=10;i++)
if(strcmp(num,chi[i])==0)
return 1;
return 0;
}
else if(strlen(num)==4){
if(num_legal(&num[2])==1){ //第二个字是零到十
if(strcmp(&num[2],"十")==0){ //第二个字是十
num[2]=0;
if(strcmp(num,"零")==0||strcmp(num,"一")==0||strcmp(num,"十")==0)
return 0;
return num_legal(num);
}
if(strcmp(&num[2],"零")==0)return 0; //第二个字不能是零
if(num_legal(&num[2])==1){ //第二个字是一到九
num[2]=0;
if(strcmp(num,"十")==0) //第一个字是十
return 1;
return 0;
}
}
return 0;
}
else if(strlen(num)==6){ //三个字
if(num_legal(&num[4])==1){ //第三个字是零到十
if(strcmp(&num[4],"零")==0||strcmp(&num[4],"十")==0)
return 0;
num[4]=0;
if(strcmp(&num[2],"十")!=0)
return 0;
num[2]=0;
if(num_legal(num)==0||strcmp(num,"零")==0||strcmp(num,"十")==0)
return 0;
return 1;
}
return 0;
}
}
int equal_legal(char equal[]) //等于合法性
{
if(strcmp(equal,"等于")==0)
return 1;
return 0;
}
int to_num(char num2[]) //汉字转数字
{
int i;
char num[10],chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
strcpy(num,num2);
if(strlen(num)==2){ //输入一位数
for(i=0;i<=10;i++)
if(strcmp(num,chi[i])==0)
return i;
}
else if(strlen(num)==4){ //输入2个汉字,十几或几十
if(num[0]==-54&&num[1]==-82) //十几
return 10+to_num(&num[2]); //&num[2]是个位数
else{ //几十
num[2]=0; //只有第一个汉字有效
return to_num(num)*10;
}
}
else{ //三个汉字,几十几
num[2]=0;
return to_num(num)*10+to_num(&num[4]);
}
}
int is_defined(char vari[]) //判断变量是否已经被定义
{
int i;
for(i=0;strlen(var[i].chi)!=0;i++)
if(strcmp(vari,var[i].chi)==0)
return 1;
return 0;
}
void print_chi(int engv) //数字转汉字并输出
{
char chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
if(engv<=10){
printf("%s",chi[engv]);
}
else if(engv<20){
printf("十");
print_chi(engv%10);
}
else{
print_chi(engv/10);
printf("十");
if(engv%10!=0) //如果是整十的数,不出几十零,而是几十
print_chi(engv%10);
}
}
void look(char vari[]) //看看函数
{
int i;
for(i=0;strlen(var[i].chi)!=0;i++)
if(strcmp(vari,var[i].chi)==0){
print_chi(var[i].engv);
break;
}
printf("\n");
}
int compute_legal(char compute[]) //运算汉字合法性
{
if(strcmp(compute,"增加")==0||strcmp(compute,"减少")==0)
return 1;
return 0;
}
void computef(char vari[],char com[],char num[]) //计算加减法
{
int i;
if(strcmp(com,"增加")==0){
for(i=0;strlen(var[i].chi)!=0;i++)
if(strcmp(vari,var[i].chi)==0){
if((var[i].engv+to_num(num))>=100)
printf("增加的数值过大\n");
else
var[i].engv+=to_num(num);
break;
}
}
else{
for(i=0;strlen(var[i].chi)!=0;i++)
if(strcmp(vari,var[i].chi)==0){
if((var[i].engv-to_num(num))<0)
printf("减少的数值过大\n");
else
var[i].engv-=to_num(num);
break;
}
}
}
void OpDefine()
{
int i=0;
char vari[10],num[10],equal[10];
scanf("%s%s%s",vari,equal,num);
if(var_legal(vari)==0||num_legal(num)==0||equal_legal(equal)==0)
error();
else{
var[i].engv=to_num(num);
strcpy(var[i].chi,vari);
i++;
}
}
void OpLook()
{
char vari[10];
scanf("%s",vari);
if(is_defined(vari)==0)
error();
else
look(vari);
}
void OpCom(char op[10])
{
int i=0,j;
char num[10],compute[10];
if(is_defined(op)==0)
error();
else{
scanf("%s%s",compute,num);
if(compute_legal(compute)==0||num_legal(num)==0)
error();
else{
computef(op,compute,num);
}
}
}
int main() //主函数
{
int i=0,j;
char op[10],vari[10],num[10],compute[10],equal[10];
while(1){
scanf("%s",op); //输入第一个词
if(op_legal(op)==0)
error();
else{
if(strcmp(op,"整数")==0) //第一个词是整数就进行变量定义
OpDefine();
else if(strcmp(op,"看看")==0) //第一个词是看看
OpLook();
else //第一个词是变量名,进行计算
OpCom(op);
}
}
return 0;
}
样例
二、把作业推送到Github仓库
首先下载github desktop,并复制一个仓库
然后将作业相关内容复制到该目录下,上传到仓库
三、制作编译脚本
本来完全不懂什么是编译脚本,后来参考了同学的博客,也查了许多资料
我用了windows批处理进行编译,成功生成lang.exe文件
四、制作测试脚本
程序中我觉得最重要的是汉字与数字的转换
于是我测试了以下三个函数
- 数字合法性函数(用于判断输入的数字是否合法)
- 汉字转数字函数
- 数字转汉字输出函数
代码如下
#include
#include
#include
#include
#include
struct Var{ //定义结构体,将汉字和英文变量一一对应
int engv; //英文变量
char chi[20]; //汉字变量
};
struct Var var[100]={0,""};
void error() //错误输出
{
printf("你写错啦!!!\n");
}
int num_legal(char num2[]) //数字合法性
{
int i;
char num[10],chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
strcpy(num,num2);
if(strlen(num)==2){
for(i=0;i<=10;i++)
if(strcmp(num,chi[i])==0)
return 1;
return 0;
}
else if(strlen(num)==4){
if(num_legal(&num[2])==1){ //第二个字是零到十
if(strcmp(&num[2],"十")==0){ //第二个字是十
num[2]=0;
if(strcmp(num,"零")==0||strcmp(num,"一")==0||strcmp(num,"十")==0)
return 0;
return num_legal(num);
}
if(strcmp(&num[2],"零")==0)return 0; //第二个字不能是零
if(num_legal(&num[2])==1){ //第二个字是一到九
num[2]=0;
if(strcmp(num,"十")==0) //第一个字是十
return 1;
return 0;
}
}
return 0;
}
else if(strlen(num)==6){ //三个字
if(num_legal(&num[4])==1){ //第三个字是零到十
if(strcmp(&num[4],"零")==0||strcmp(&num[4],"十")==0)
return 0;
num[4]=0;
if(strcmp(&num[2],"十")!=0)
return 0;
num[2]=0;
if(num_legal(num)==0||strcmp(num,"零")==0||strcmp(num,"十")==0)
return 0;
return 1;
}
return 0;
}
}
int to_num(char num2[]) //汉字转数字
{
int i;
char num[10],chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
strcpy(num,num2);
if(strlen(num)==2){ //输入一位数
for(i=0;i<=10;i++)
if(strcmp(num,chi[i])==0)
return i;
}
else if(strlen(num)==4){ //输入2个汉字,十几或几十
if(num[0]==-54&&num[1]==-82) //十几
return 10+to_num(&num[2]); //&num[2]是个位数
else{ //几十
num[2]=0; //只有第一个汉字有效
return to_num(num)*10;
}
}
else{ //三个汉字,几十几
num[2]=0;
return to_num(num)*10+to_num(&num[4]);
}
}
void print_chi(int engv) //数字转汉字并输出
{
char chi[20][5]={"零","一","二","三","四","五","六","七","八","九","十"};
if(engv<=10){
printf("%s",chi[engv]);
}
else if(engv<20){
printf("十");
print_chi(engv%10);
}
else{
print_chi(engv/10);
printf("十");
if(engv%10!=0) //如果是整十的数,不出几十零,而是几十
print_chi(engv%10);
}
}
int main() //主函数
{
int num[10]={0,3,10,13,17,20,25,30,37,77},i;
char chi[20][10]={"零","一","五","十","十一","十三","二十","七十","二十六","三十八","七十五","九十九","一百","三七","增加","看看","零三","哈哈","六六","作业"};
printf("开始测试数字合法性函数\n");
for(i=0;i<20;i++){
if(i<=11){
printf("chi=%s legal=%d ",chi[i],num_legal(chi[i]));
if(num_legal(chi[i])==1)
printf("Pass\n");
else
printf("Fail\n");
}
else{
printf("chi=%s legal=%d ",chi[i],num_legal(chi[i]));
if(num_legal(chi[i])==0)
printf("Pass\n");
else
printf("Fail\n");
}
}
printf("开始测试数字转汉字函数\n");
for(i=0;i<10;i++){
printf("num=%d chi=",num[i]);
print_chi(num[i]);
printf(" Pass\n");
}
printf("开始测试汉字转数字函数\n");
for(i=0;i<=11;i++){
printf("chi=%s num=%d ",chi[i],to_num(chi[i]));
printf("Pass\n");
}
printf("测试完毕\n");
system("pause");
return 0;
}
部分测试结果
五、添加文件读取的功能
我通过查资料了解需要用freopen函数
但是程序会不断读取最后一个字符串,造成死循环
经过查找资料明白需要用feof函数读取到文件结束
但是又遇到一个问题,那就是读取汉字的时候会变成乱码
询问同学后明白了是编码格式的问题,于是我就把txt文件另存为成ANSI格式
运行成功