这个作业属于哪个课程 | 2020面向对象程序设计 |
---|---|
这个作业要求在哪里 | 面向对象程序设计寒假作业2 |
这个作业的目标 | 1. 继续完成编程题。 2.新建一个github仓库,并把作业推送到该仓库。3. 发布博客。 |
作业正文 | 作业链接 |
其他参考文献 | 零基础的git教程、windows批处理、windows批处理视频、freopen()函数 |
一.实践题
新建一个github仓库,使用git,或者github desktop把接下去的编程题的代码及测试脚本传到这个仓库。
请使用.gitignore文件忽略不要上传的文件。用法自行百度。
首先在github创建了一个仓库Fzu_opp_homework,
然后下载了github desktop,将要上传的文件拉到仓库文件下,完成clone。
再通过->repository->push来完成
二.编程题(请使用C语言或者C++完成以下题目):
1. 继续完成作业一的编程题。
优化架构,一般要求每个函数长度不超过15行。
优化规范,尤其是命名规范。
这个编程题我将它主要分成四大块,分别是转换,输入,输出,主函数。其中转换由change(),change(),chanege3()三个函数组成。
change()函数是实现对输入的汉字进行转换,我对它进行优化。
下面是我原来的代码:
int change(char a[]){
int n;
if(!strcmp(a,"零")) n=0;
else if(!strcmp(a,"一")) n=1;
else if(!strcmp(a,"二")) n=2;
else if(!strcmp(a,"三")) n=3;
else if(!strcmp(a,"四")) n=4;
else if(!strcmp(a,"五")) n=5;
else if(!strcmp(a,"六")) n=6;
else if(!strcmp(a,"七")) n=7;
else if(!strcmp(a,"八")) n=8;
else if(!strcmp(a,"九")) n=9;
return n;
}
下面是我优化后的:
int change(char a[]){//将汉字转化成数字进行运算
int n;
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
for(int i=0;i<10;i++){
if(!strcmp(a,str[i])) return n=i;
}
}
change1()和change2()是共同实现对数字转换为汉字的功能,能对整十和十几的数进行特殊处理:
下面是change1()优化前的:
void change1(int n,char a[]){//将汉字转化成数字
switch(n){
case 0:strcpy(a,"零");break;
case 1:strcpy(a,"一");break;
case 2:strcpy(a,"二");break;
case 3:strcpy(a,"三");break;
case 4:strcpy(a,"四");break;
case 5:strcpy(a,"五");break;
case 6:strcpy(a,"六");break;
case 7:strcpy(a,"七");break;
case 8:strcpy(a,"八");break;
case 9:strcpy(a,"九");break;
}
}
下面是优化后的:
void change1(int n,char a[]){//将汉字转化成数字
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
strcpy(a,str[n]);
}
void change2(int n,char cnum[]){
char a[20];
if(n<10){change1(n,a),strcpy(cnum,a);}
else{int t;
t=n/10,n=n%10;
if(t!=1){//考虑“十”和“一十”的差别
change1(t,a),strcpy(cnum,a),strcat(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}//考虑末尾是零的情况
}
else{strcpy(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}
}
}
}
接下来是输入函数in():
int in(void){//输入函数
scanf("%s",name1);
if(!strcmp(name1,"看看")) return 0;
if(strcmp(name1,name)!=0) return 1;
scanf("%s %s",fu,num);
if(strcmp(fu,"增加")) n-=change(num);
else n+=change(num);
}
然后是输出函数out():
void out(int n){
if(n==-1) printf("Error");
else{
char cnum[20];
change2(n,cnum);
printf("%s",cnum);
}
}
最后是我完整的代码:
#include
#include
int n;
char type[20],name[20],name1[20],fu[20],num[20];
int change(char a[]){//将汉字转化成数字进行运算
int n;
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
for(int i=0;i<10;i++){
if(!strcmp(a,str[i])) return n=i;
}
}
void change1(int n,char a[]){//将汉字转化成数字
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
strcpy(a,str[n]);
}
void change2(int n,char cnum[]){
char a[20];
if(n<10){change1(n,a),strcpy(cnum,a);}
else{int t;
t=n/10,n=n%10;
if(t!=1){//考虑“十”和“一十”的差别
change1(t,a),strcpy(cnum,a),strcat(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}//考虑末尾是零的情况
}
else{strcpy(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}
}
}
}
int in(void){//输入函数
scanf("%s",name1);
if(!strcmp(name1,"看看")) return 0;//输入结束标志
if(strcmp(name1,name)) return 1;//判断运算对象是不是定义的变量,否则不进行还回主函数
scanf("%s %s",fu,num);
if(strcmp(fu,"增加")) n-=change(num);//判断运算符号
else n+=change(num);
return 1;
}
void out(int n){//输出函数
char cnum[20];
change2(n,cnum);
printf("%s",cnum);
}
int main(int argc,char *argv[]){
freopen(argv[1],"r",stdin);
scanf("%s %s %s %s",type,name,fu,num);
n=change(num);
if(!strcmp(type,"整数")){//判断类型是否为“整数”
while(1){
if(!in()) break;
}
scanf("%s",name1);
if(strcmp(name1,name)||n<0||n>99){// 判断最后询问对象是否是该变量或数字不在0~99的范围内 ,否则报错
out(-1); return 0;}
else out(n);
}
else out(-1);
return 0;
}
2. 制作一个编译脚本,运行该脚本可以编译你的代码,可选的脚本语言,python(2.7),windows批处理,powershell,shell。
示例脚本:
gcc 1.cpp -o lang.exe
对于编译脚本,我选择了windows批处理,刚开始的时候感觉自己什么都不懂,连编译脚本要怎么写写在哪都不清楚,无从下手,最后只能硬着头皮在网上查资料,而网上的资料比较零碎对于我这初学者也比较难啃,然后就在网上查什么是编译脚本,之后才有初步了解,然后再查windows批处理的知识,对那些命令进行学习,最后在b上看到教学视频,有了更深的理解.
下面是我的脚本:
@echo off
if exist 作业2.exe (echo 已完成) else (echo 未编译)
echo ......开始编译......
gcc Lin.cpp -o 作业2.exe
echo ......已结束......
if exist 作业2.exe (echo 已编译) else (echo 未编译)
pause
我把Lin.cpp文件存在和test1.bat同一个根目录下,在cmd下用if看有没有编译,然后进行编译,最后再用if检查有没有编译。过程如下:
3. 进行单元测试,即测试每一个函数,并制作一个测试脚本,运行该脚本可以进行测试,并显示测试结果。
示例脚本:
gcc 1.cpp test.cpp -o test.exe
test
我并不是很理解这个怎么做,看有些同学提交的作业中是再写一个函数的代码,用cmd进行测试,我也不了解其他方法,也用了这个办法。
然后我对识别输入的change()函数进行测试
#include
#include
int change(char a[]){
int n;
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
for(int i=0;i<10;i++){
if(!strcmp(a,str[i])) return n=i;
}
}
int main(){
char a[10][4]={"零","一","二","三","四","五","六","七","八","九"};
for(int i=0;i<10;i++)
printf("%s %d\n",a[i],change(a[i]));
return 0;
}
因为已经编译过了,我的脚本代码如下:
@echo off
test2
然后也测试了数字转汉字的代码
#include
#include
void change1(int n,char a[]){//将汉字转化成数字
char str[10][4]={"零","一","二","三","四","五","六","七","八","九"};
strcpy(a,str[n]);
}
void change2(int n,char cnum[]){
char a[20];
if(n>=0&&n<=99){//判断数字是否合法
if(n<10){change1(n,a),strcpy(cnum,a);}
else{int t;
t=n/10,n=n%10;
if(t!=1){//考虑“十”和“一十”的差别
change1(t,a),strcpy(cnum,a),strcat(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}//考虑末尾是零的情况
}
else{strcpy(cnum,"十");
if(n!=0){change1(n,a),strcat(cnum,a);}
}
}
}
}
int main(){
for(int i=0;i<100;i++){
char cnum[20];
change2(i,cnum);
printf("%d %s\n",i,cnum);
}
return 0;
}
@echo off
test3
过程如图
添加功能
在作业一编程题的基础上添加以下功能:
通过命令行读取一个文件,然后运行这个文件。如我的程序叫lang,lang 1.txt代表我要运行1.txt这个文本中的代码。
假设我的1.txt内容如下:
整数 钱包 等于 零
钱包 增加 四
钱包 减少 三
看看 钱包
输入lang 1.txt后,命令行输出一。
我在同学那了解到要用文件下的freopen()函数,在网上百度了解后,将主函数修改为:
int main(int argc,char *argv[]){
freopen(argv[1],"r",stdin);
return 0;
}