2020寒假作业-2 一、编程题优化 二、把作业推送到Github仓库 三、制作编译脚本 四、制作测试脚本 五、添加文件读取的功能

这个作业属于哪个课程 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<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
struct Var{  //定义结构体,将汉字和英文变量一一对应 
		int engv;          //英文变量 
		char chi[20];      //汉字变量 
	};
struct Var var[100]={0,""};
void error()  //错误输出 
{
	printf("你写错啦!!!
");
}
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("
");
}
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("增加的数值过大
");
				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("减少的数值过大
");
				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;
}

样例

样例一
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能
样例二
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能
样例三
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能
样例四
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能

二、把作业推送到Github仓库

首先下载github desktop,并复制一个仓库
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能
然后将作业相关内容复制到该目录下,上传到仓库
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能

三、制作编译脚本

本来完全不懂什么是编译脚本,后来参考了同学的博客,也查了许多资料
我用了windows批处理进行编译,成功生成lang.exe文件
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能

四、制作测试脚本

程序中我觉得最重要的是汉字与数字的转换
于是我测试了以下三个函数

  • 数字合法性函数(用于判断输入的数字是否合法)
  • 汉字转数字函数
  • 数字转汉字输出函数
    代码如下
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
struct Var{  //定义结构体,将汉字和英文变量一一对应 
		int engv;          //英文变量 
		char chi[20];      //汉字变量 
	};
struct Var var[100]={0,""};
void error()  //错误输出 
{
	printf("你写错啦!!!
");
}
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("开始测试数字合法性函数
");
	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
");
			else
				printf("Fail
");
		}
		else{
			printf("chi=%s legal=%d ",chi[i],num_legal(chi[i]));
			if(num_legal(chi[i])==0)
				printf("Pass
");
			else
				printf("Fail
");
		}
	}
	printf("开始测试数字转汉字函数
");
	for(i=0;i<10;i++){
		printf("num=%d chi=",num[i]);
		print_chi(num[i]);
		printf(" Pass
");
	}
	printf("开始测试汉字转数字函数
");
	for(i=0;i<=11;i++){
		printf("chi=%s num=%d ",chi[i],to_num(chi[i]));
		printf("Pass
");
	}
	printf("测试完毕
");
	system("pause");
	return 0;
}

用命令行生成测试脚本
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能

部分测试结果

2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能

五、添加文件读取的功能

我通过查资料了解需要用freopen函数
但是程序会不断读取最后一个字符串,造成死循环
经过查找资料明白需要用feof函数读取到文件结束
但是又遇到一个问题,那就是读取汉字的时候会变成乱码
询问同学后明白了是编码格式的问题,于是我就把txt文件另存为成ANSI格式
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能
运行成功
2020寒假作业-2
一、编程题优化
二、把作业推送到Github仓库
三、制作编译脚本
四、制作测试脚本
五、添加文件读取的功能