面向对象程序设计寒假作业2(编程题2)
这个作业属于哪个课程 | 2020面向对象程序设计张栋班 |
---|---|
这个作业要求在哪里 | 面向对象程序设计寒假作业2 |
这个作业的目标 | 制作一个编译运行脚本、进行单元测试显示测试结果、通过命令行读取一个文件,然后运行这个文件 |
其他参考文献 | Windows下Python3实现C++多文件编译脚本、Windows批处理文件(.bat文件和.cmd文件)介绍以及简单使用、关于C/C++中main函数参数的学习、C/C++中的freopen()函数使用详解 |
使用python作为脚本编程语言(失败了)
我首先了解到python自带的os模块可以调用cmd控制台命令,于是查找方法:os.system()可以向cmd控制台传参,于是我准备一个文件夹,向其中添加1.txt、lang.c、编译脚本.py,贴出脚本里的代码:
import os
input = input("请输入:")
input = input.split(" ")
CFile = input[0]
InputFile = input[1]
path = os.getcwd() + "\C"
os.chdir(path)
cmd1 = "g++ " + CFile + ".c"
cmd2 = "a.exe"
with open(path + "\\" + InputFile) as f:
text = f.read()
os.system(cmd1)
os.system(cmd2 + '\n' + text + '\n')
出现的问题,每次使用os.system()时都时重新打开一个cmd控制台,没有办法做到连续输入导致运行程序后会卡在输入阶段,无法停止,百度过后找寻不到可以连续输入的方法。
已经出现a.exe可执行文件,点击删除a.exe文件显示该文件正在运行:
暂停脚本代码后才可删除。
参考几位已提交同学和题目中的示例脚本后发现自己对于脚本理解错误,所以经过学习后再进行编写
经过粗略的学习,我在C文件夹中放入我准备好的lang.c文件
然后使用Notepad++(这里打个广告)进行编写,我原本以为会十分麻烦,但是经过学习,我写了一个简单但是高效的脚本文件test1.bat:
@echo off
title 编译运行脚本
g++ -o lang.exe lang.c
lang.exe
pause
del lang.exe
我在这里描述一下脚本大概的过程,首先关闭echo,然后将cmd的标题改成“编译运行脚本”,这里我查找资料,中文编码应选择ANSI编码,否者会出现乱码,接着就是编译lang.c的语句以及执行lang.exe大的语句,在然后就是在程序中执行自己的输入输出,最后删除lang.exe文件。
放上图:
这里是已经准备好的C文件夹:
然后点击test.bat:
可以看到已经出现lang.exe文件,接着是输入和输出:
再然后随便摁个空格就好了,C文件夹中也没有了lang.exe文件:
接着是测试单元
参考已经提交的几位同学,大概了解了单元测试的模式,观看我自己的代码,我用到了四个函数,其中核心calculate
函数依托于hz_to_num
函数,而hz_to_num
函数又依托于hz_judge
函数,而我们正常的进行输入输出就可以判断num_to_hz
函数的正确性,所以我我只需测试hz_judge
和hz_to_num
两个单元即可,这里,我只对hz_to_num
进行测试,由于有一百个数,这里用抽号机抽取十个进行测试:
这里准备了lang.h:
#include<stdio.h>
#include<string.h>
int hz_judge(char* str);
int calculate(int num,char* command,char* number);
int hz_to_num(char* str);
int num_to_hz(int num);
char hz[11][10]={"零","一","二","三","四","五","六","七","八","九","十"};
char keywords[5][20]={"整数","等于","增加","减少","看看"};
int hz_judge(char* str){
int i;
for(i=0;i<11;i++){
if(strcmp(str,hz[i])==0){
return i;
}
}
return -1;
}
int calculate(int num,char* command,char* number){
int n;
if(strcmp(command,keywords[2])==0){
n=hz_to_num(number);
return num+=n;
}
else if(strcmp(command,keywords[3])==0){
n=hz_to_num(number);
return num-=n;
}
else{
return -1;
}
}
int hz_to_num(char* str)
{
char a[3],b[3],c[3];
int len,i,j;
len=strlen(str);
if(len==4){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
b[0]=str[2];
b[1]=str[3];
b[2]=0;
if((strcmp(a,hz[10])!=0&&strcmp(b,hz[10])!=0)||(strcmp(a,hz[10])==0&&strcmp(b,hz[10])==0)){
return -1;
}
else if(strcmp(a,hz[10])==0){
return hz_judge(b)+10;
}
else{
return hz_judge(a)*10;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
c[0]=str[2];
c[1]=str[3];
c[2]=0;
b[0]=str[4];
b[1]=str[5];
b[2]=0;
if(strcmp(a,hz[1])==0||strcmp(c,hz[10])!=0||hz_judge(a)==-1||hz_judge(b)==-1){
return -1;
}
return hz_judge(a)*10+hz_judge(b);
}
else if(len==2){
if(hz_judge(str)==-1){
return -1;
}
return hz_judge(str);
}
}
int num_to_hz(int num){
if(num>=10){
if(num%10==0){
if(num==10){
printf("%s\n",hz[10]);
}
else{
printf("%s%s\n",hz[num/10],hz[10]);
}
}
else{
if(num<20){
printf("%s%s\n",hz[10],hz[num%10]);
}
else{
printf("%s%s%s\n",hz[num/10],hz[10],hz[num%10]);
}
}
}
else{
printf("%s\n",hz[num]);
}
}
这个是测试代码:
#include"lang.h"
char str[10][8]={"六十五","九十六","二十七","六十四","九十一","十四","二十","十九","四十三","九十二"};
int main()
{
if(hz_to_num(str[0])==65){
printf("六十五 %d pass\n",hz_to_num(str[0]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[0]));
}
if(hz_to_num(str[1])==96){
printf("九十六 %d pass\n",hz_to_num(str[1]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[1]));
}
if(hz_to_num(str[2])==27){
printf("二十七 %d pass\n",hz_to_num(str[2]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[2]));
}
if(hz_to_num(str[3])==64){
printf("六十四 %d pass\n",hz_to_num(str[3]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[3]));
}
if(hz_to_num(str[4])==91){
printf("九十一 %d pass\n",hz_to_num(str[4]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[4]));
}
if(hz_to_num(str[5])==14){
printf("十四 %d pass\n",hz_to_num(str[5]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[5]));
}
if(hz_to_num(str[6])==20){
printf("二十 %d pass\n",hz_to_num(str[6]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[6]));
}
if(hz_to_num(str[7])==19){
printf("十九 %d pass\n",hz_to_num(str[7]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[7]));
}
if(hz_to_num(str[8])==43){
printf("四十三 %d pass\n",hz_to_num(str[8]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[8]));
}
if(hz_to_num(str[9])==92){
printf("九十二 %d pass\n",hz_to_num(str[9]));
}
else{
printf("OutPut is %d,WRONG!!!\n",hz_to_num(str[9]));
}
}
这个是脚本:
@echo off
title 测试运行脚本1
g++ -o test1.exe test1.c
test1.exe
pause
del test1.exe
测试代码有点长,下面是通过脚本运行后的样子:
测试成功!!
下面是文件输入输出测试,吸取前几位做完同学的经验,查找了有关文件输入输出的资料,需要学习freopen函数:
FILE * freopen(const char *filename, const char *mode,FILE *stream);
- 参数说明:
- filename:要打开的文件名;
- mode:文件打开的模式,和fopen中的模式(r/w)相同。
- stream:文件指针,通常使用标准流文件(stdin/stdout/stderr)
再这篇博客里已经讲的比较清楚,所以我就不详写,直接贴出main函数修改后的代码:
#include<stdio.h>
#include<string.h>
int hz_judge(char* str);
int calculate(int num,char* command,char* number);
int hz_to_num(char* str);
int num_to_hz(int num);
char hz[11][10]={"零","一","二","三","四","五","六","七","八","九","十"};
char keywords[5][20]={"整数","等于","增加","减少","看看"};
int hz_judge(char* str){
int i;
for(i=0;i<11;i++){
if(strcmp(str,hz[i])==0){
return i;
}
}
return -1;
}
int calculate(int num,char* command,char* number){
int n;
if(strcmp(command,keywords[2])==0){
n=hz_to_num(number);
return num+=n;
}
else if(strcmp(command,keywords[3])==0){
n=hz_to_num(number);
return num-=n;
}
else{
return -1;
}
}
int hz_to_num(char* str)
{
char a[3],b[3],c[3];
int len,i,j;
len=strlen(str);
if(len==4){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
b[0]=str[2];
b[1]=str[3];
b[2]=0;
if((strcmp(a,hz[10])!=0&&strcmp(b,hz[10])!=0)||(strcmp(a,hz[10])==0&&strcmp(b,hz[10])==0)){
return -1;
}
else if(strcmp(a,hz[10])==0){
return hz_judge(b)+10;
}
else{
return hz_judge(a)*10;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
c[0]=str[2];
c[1]=str[3];
c[2]=0;
b[0]=str[4];
b[1]=str[5];
b[2]=0;
if(strcmp(a,hz[1])==0||strcmp(c,hz[10])!=0||hz_judge(a)==-1||hz_judge(b)==-1){
return -1;
}
return hz_judge(a)*10+hz_judge(b);
}
else if(len==2){
if(hz_judge(str)==-1){
return -1;
}
return hz_judge(str);
}
}
int num_to_hz(int num){
if(num>=10){
if(num%10==0){
if(num==10){
printf("%s\n",hz[10]);
}
else{
printf("%s%s\n",hz[num/10],hz[10]);
}
}
else{
if(num<20){
printf("%s%s\n",hz[10],hz[num%10]);
}
else{
printf("%s%s%s\n",hz[num/10],hz[10],hz[num%10]);
}
}
}
else{
printf("%s\n",hz[num]);
}
}
int main(int argc,char *argv[]){
printf("欢迎使用,请按以下要求输入:\n1.该程序仅支持两位数以内数字输入,计算结果也应保证在两位数范围内且不为负数\n2.在程序第一行应定义变量,遵循如下格式(整数 定义变量名 等于 定义数字)\n3.输入数字请遵循以下规范:\n\t(1~9):一~~九、\n\t(11~19):十一~~十九、\n\t(21~29、31~39、···):二十一~~二十九、三十一~~三十九、···\n\t(10的倍数):十、二十、三十、···\n4.变量增加减少请按照(定义变量名 增加/减少 数字)进行\n5.查看变量结束程序请按如下格式(看看 定义变量名)\n");
if(argc!=1){
freopen(argv[1],"r",stdin);
}
char name[20],command[100][20];
int i=0,target;
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[0])==0){
scanf("%s",name);
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[1])==0){
scanf("%s",command[i++]);
target=hz_to_num(command[i-1]);
if(target==-1){
printf("数字格式出错,请参考要求第2点");
return 0;
}
}
else{
printf("输入错误!(应输入:等于 ~)\n");
return 0;
}
}
else{
printf("错误,请先定义变量!(应输入:整数 ~)\n");
return 0;
}
while(1){
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[4])==0){
scanf("%s",command[i++]);
if(strcmp(command[i-1],name)==0){
num_to_hz(target);
return 0;
}
else{
printf("输入名称错误!(请输入:定义变量名)\n");
return 0;
}
}
else if(strcmp(command[i-1],name)==0){
scanf("%s",command[i++]);
scanf("%s",command[i++]);
if(hz_to_num(command[i-1])==-1){
printf("数字格式出错,请参考要求第2点");
return 0;
}
if(calculate(target,command[i-2],command[i-1])==-1){
return 0;
}
else{
target=calculate(target,command[i-2],command[i-1]);
}
}
else{
printf("输入名称错误!(请输入:定义变量名 或 看看)\n");
return 0;
}
}
}
提前准备1.txt和2.txt文件:
编译后,用cmd到该文件夹目录下,分别输入lang 1.txt
和lang 2.txt
:
到此结束任务。