面向对象程序设计2020第二次作业

面向对象程序设计2020第一次作业

这个作业属于哪个课程 2020面向对象程序设计张栋班
这个作业要求在哪里 寒假作业2
这个作业的目标 完善代码、新建GitHub仓库并上传代码、制作编译脚本、进行单元测试并制作测试脚本、添加文件读取功能
作业正文 第二次作业
其它参考文献 git教程
shell教程
执行脚本的三种方式
C语言命令行参数的使用
git和GitHub教程

注: 系统是Mac OS


实践题

  • 创建SSH Key
    • 参考文章
  • 新建仓库
    面向对象程序设计2020第二次作业_第1张图片

  • clone到本地
    面向对象程序设计2020第二次作业_第2张图片

  • 其中仓库地址从这里复制

面向对象程序设计2020第二次作业_第3张图片

  • 创建.gitignore文件,配置后传到仓库(具体配置到gitignore模版找自己需要的,再复制组合到自己的.gitignore文件中)

面向对象程序设计2020第二次作业_第4张图片

  • 将代码放到该文件夹后传到仓库

面向对象程序设计2020第二次作业_第5张图片

  • push时如果出现问题,可参考下图

面向对象程序设计2020第二次作业_第6张图片


编程题

一、优化代码

  • 能够输入两位数三位数,如“二十”,“三十三”。具体实现在processStringToInt函数。
  • 分为几个函数,使含义更清晰,可读性提高
int convertToInt(char str[]);// 中文转为数字
char* convertToString(int n);// 数字转为中文
void error(void);//输出错误
void execute(void);// 执行
int processStringToInt(char number[]);// 在convertToInt函数的基础上,实现处理两位数和三位数中文
void printResult(int n); // 输出结果
  • 优化后完整代码
//main.h
#ifndef UNTITLED_MAIN_H
#define UNTITLED_MAIN_H

#include 
#include 
typedef struct variable
{
    char name[1000];
    int value;
} var;

int convertToInt(char str[]);// 中文转为数字
char* convertToString(int n);// 数字转为中文
void error(void);//输出错误
void execute(void);// 执行
int processStringToInt(char number[]);// 在convertToInt函数的基础上,实现处理两位数和三位数中文
void printResult(int n); // 输出结果

#endif //UNTITLED_MAIN_H



// main.c
#include "main.h"
int main()
{
    char integer[6];
    scanf("%s",integer);
    if(strcmp(integer,"整数")){ // 判断第一个词是否为“整数”
        error();
    }
    else{
        execute();//执行
    }
    return 0;
}

//error.c
#include "main.h"
void error()
{
    printf("格式错误\n");
}

// convertToInt.c
#include "main.h"
int convertToInt(char str[])
{
    if(!strcmp(str,"零"))    return 0;
    else if(!strcmp(str,"一"))    return 1;
    else if(!strcmp(str,"二"))    return 2;
    else if(!strcmp(str,"三"))    return 3;
    else if(!strcmp(str,"四"))    return 4;
    else if(!strcmp(str,"五"))    return 5;
    else if(!strcmp(str,"六"))    return 6;
    else if(!strcmp(str,"七"))    return 7;
    else if(!strcmp(str,"八"))    return 8;
    else if(!strcmp(str,"九"))    return 9;
    else if(!strcmp(str,"十"))    return 10;
    else return -1;
}

//convertToString.c
char* convertToString(int n)
{
    if(n == 0)  return "零";
    else if(n == 1) return "一";
    else if(n == 2) return "二";
    else if(n == 3) return "三";
    else if(n == 4) return "四";
    else if(n == 5) return "五";
    else if(n == 6) return "六";
    else if(n == 7) return "七";
    else if(n == 8) return "八";
    else if(n == 9) return "九";
    else if(n == 10) return "十";
    else return "Error";
}

//execute.c
#include "main.h"
void execute()
{
    var a;
    char name[1000],operator[6],number[8];
    scanf("%s%s%s",a.name,operator,number);
    if(strcmp(operator,"等于")){
        error();
    }
    else{
        if(processStringToInt(number) == -1)    error();
        else {
            a.value = processStringToInt(number); //赋初始值
            scanf("%s", name);
            //循环执行到某行首个字符串不是变量名
            while (!strcmp(name, a.name)) {
                scanf("%s%s", operator, number);
                if (!strcmp(operator, "增加")) {
                    a.value += processStringToInt(number);
                } else if (!strcmp(operator, "减少")) {
                    a.value -= processStringToInt(number);
                } else {
                    error();
                    break;
                }
                scanf("%s", name);
            }
            if (!strcmp(name, "看看")) {
                scanf("%s", name);
                if (!strcmp(name, a.name))//“看看”后面输入的内容得和前面的变量名称相同
                {
                    printResult(a.value);
                } else {
                    printf("不存在此变量\n");
                }
            }
        }
    }
}

//processStringToInt.c
#include "main.h"
int processStringToInt(char number[])
{
    char str1[3],str2[3],str3[3];
    int sum = 0;
    strncpy(str1,number,2);
    str1[2] = '\0';
    sum = convertToInt(str1);
    if(strlen(number) == 4)//输入两位数中文
    {
        strncpy(str2,number+2,2);//从number字符串的第三个字符number[2]开始复制
        str2[2] = '\0'; //结尾要加\0,否则会出错
        if(convertToInt(str2) == 10)
            sum = convertToInt(str2) * convertToInt(str1);//大于10且为十的整数倍
        else if(convertToInt(str2) != -1)
            sum = convertToInt(str2) + convertToInt(str1); //十一到十九
        else
            sum = -1;
    }
    if(strlen(number) == 6)//输入三位数中文
    {
        strncpy(str3,number+4,2);
        str3[2] = '\0';
        sum = convertToInt(str1)*10 + convertToInt(str3);   // 二十一~九十九(不包括十的整数倍)
    }
    return sum;
}

//printResult.c
#include "main.h"
void printResult(int n)
{
    if(n <= 10)
    {
        printf("%s",convertToString(n));
    }
    else if(n % 10 == 0 && n < 100)
    {
        printf("%s十",convertToString(n/10));//十的整数倍输出为几十而不是几零
    }
    else if(n < 20)
    {
        n %= 10;
        printf("十%s",convertToString(n));//输出十几而不是一十几
    }
    else if(n < 100)
    {
        printf("%s十%s",convertToString(n/10),convertToString(n%10));
    }
    else
    {
        printf("变量数值超出范围");
        }
}

二、编译脚本

  • 代码如下,所使用脚本语言为shell
#!/bin/bash

fileName=$1 #注意不能有空格 #$0指此文件名 $1指运行此文件时的第一个参数名,也就是要编译的文件名

echo "开始编译......" 
gcc $fileName -o result.out # 使用一个定义过的变量,只要在变量名前面加美元符号$即可
if [ $? == 0 ]  # $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
then    #注意中括号周围的空格
    echo "编译成功......"
    echo "开始运行......"
    ./result.out
    if [ $? == 0 ]
    then
        echo "运行结束......"
    else
        echo "运行失败......"
    fi
else
    echo "编译失败......"
fi
  • 实现效果

面向对象程序设计2020第二次作业_第7张图片

三、 单元测试

  • 一开始理解错意思了,花了好长时间学了个单元测试工具CUnit,直到助教在群里说才知道是我想多了, 当场死亡

  • 首先测试三个转换函数(test.c作了修改,感谢分享)

面向对象程序设计2020第二次作业_第8张图片


//test.c
#include "main.h"

void assert_str_equals(const char *actual, const char *expected)
{
    if (!strcmp(actual, expected))
        printf("Pass\n");
    else
        printf("Failed. actual: %s, expected: %s\n", actual, expected);
    
}
void assert_int_equals(int actual, int expected)
{
    if (actual == expected)
        printf("Pass\n");
    else
        printf("Failed. actual: %d, expected: %d\n", actual, expected);
    
}

void test_convertToString()
{
    printf("test_convertToString 开始----------\n");
    assert_str_equals(convertToString(0),"零");
    assert_str_equals(convertToString(1),"一");
    assert_str_equals(convertToString(2),"二");
    assert_str_equals(convertToString(3),"三");
    assert_str_equals(convertToString(4),"四");
    assert_str_equals(convertToString(5),"五");
    assert_str_equals(convertToString(6),"六");
    assert_str_equals(convertToString(7),"七");
    assert_str_equals(convertToString(8),"八");
    assert_str_equals(convertToString(9),"九");
    assert_str_equals(convertToString(10),"十");
    assert_str_equals(convertToString(11),"Error");
    assert_str_equals(convertToString(21),"Error");
    printf("test_convertToString 结束----------\n");
}

void test_convertToInt()
{
    printf("test_convertToInt 开始----------\n");
    assert_int_equals(convertToInt("零"), 0);
    assert_int_equals(convertToInt("一"), 1);
    assert_int_equals(convertToInt("二"), 2);
    assert_int_equals(convertToInt("三"), 3);
    assert_int_equals(convertToInt("四"), 4);
    assert_int_equals(convertToInt("五"), 5);
    assert_int_equals(convertToInt("六"), 6);
    assert_int_equals(convertToInt("七"), 7);
    assert_int_equals(convertToInt("八"), 8);
    assert_int_equals(convertToInt("九"), 9);
    assert_int_equals(convertToInt("十"), 10);
    assert_int_equals(convertToInt("百"), -1);
    assert_int_equals(convertToInt("十一"), -1);
    printf("test_convertToInt 结束----------\n");
}

void test_pcocessStringToInt()
{
    printf("test_pcocessStringToInt开始----------\n");
    assert_int_equals(processStringToInt("零"), 0);
    assert_int_equals(processStringToInt("六"), 6);
    assert_int_equals(processStringToInt("十一"), 11);
    assert_int_equals(processStringToInt("二十"), 20);
    assert_int_equals(processStringToInt("七十"), 70);
    assert_int_equals(processStringToInt("四十二"), 42);
    assert_int_equals(processStringToInt("九十九"), 99);
    assert_int_equals(processStringToInt("六十六"), 66);
    assert_int_equals(processStringToInt("五十三"), 53);
    assert_int_equals(processStringToInt("一百"), -1);
    assert_int_equals(processStringToInt("三百"), -1);
    printf("test_pcocessStringToInt结束----------\n");
}

int main()
{
    test_convertToInt();
    test_convertToString();
    test_pcocessStringToInt();
}
  • 测试脚本
#!/bin/bash
echo "开始编译......"
gcc test.c excute.c convertToInt.c convertToString.c error.c printResult.c processStringToInt.c
if [ $? == 0 ]
then
  echo "编译成功......"
  echo "开始运行......"
  ./a.out
  if [ $? == 0 ]
  then
    echo "运行成功......"
  else
    echo "运行失败......"
  fi
else
  echo "编译失败"
fi
  • 运行结果
    • 运行方法:在终端cd进入文件夹,然后输入 bash filename.sh(filename指的是脚本的文件名)

面向对象程序设计2020第二次作业_第9张图片

  • 上面两个函数测试过了以后,其他几个函数由运行结果来验证

面向对象程序设计2020第二次作业_第10张图片

面向对象程序设计2020第二次作业_第11张图片

面向对象程序设计2020第二次作业_第12张图片

面向对象程序设计2020第二次作业_第13张图片


四、 添加以下功能

  • 通过命令行读取一个文件,然后运行这个文件。
  • 要实现该功能,需要编写以下源程序,与要运行的程序放到同一个文件夹
//runfile.c
#include 
#include  //使用system要包含此头文件
#include 

int main(int argc,char* argv[])
{
    char cmd[100] = "gcc ";
    FILE* fp = fopen(argv[1],"r"); //argv[0]是正在执行的文件名,argv[1]是第一个参数(也就是在命令行给的所要运行的文件名)
    strcat(cmd,argv[1]);
    if(fp)
    {
        system(cmd); //system:括号里的参数是字符串,在命令行时会执行该命令
        system("./a.out");
        fclose(fp);
    }
    else
    {
        printf("can't open the file\n");
    }
    return 0;
}
  • 运行

面向对象程序设计2020第二次作业_第14张图片


  • 因为我的程序分为多个源程序文件,要运行一个文件得和其他文件一起编译,所以将runfile.c修改 ,并编写了编译运行脚本runfile.sh
#include 
#include 
#include 

int main(int argc,char* argv[])
{
    char cmd[100] = "bash runfile.sh ";
    FILE* fp = fopen(argv[1],"r");
    strcat(cmd,argv[1]);
    if(fp)
    {
        system(cmd);
        fclose(fp);
    }
    else
    {
        printf("can't open the file\n");
    }
    return 0;
}
#!/bin/bash

fileName=$1
echo "开始编译......"
gcc $fileName excute.c convertToInt.c convertToString.c error.c printResult.c processStringToInt.c
if [ $? == 0 ]
then
  echo "编译成功......"
  echo "开始运行......"
  ./a.out
  if [ $? == 0 ]
  then
    echo "运行成功......"
  else
    echo "运行失败......"
  fi
else
  echo "编译失败"
fi
  • 运行方式(结果和上文第三部分相同,就不贴图了)

面向对象程序设计2020第二次作业_第15张图片


写在最后

  • 不得不说通过第二次作业学到的东西还是很多的,很多都是之前不会的,只能现学,关键是有时候题目都不知道什么意思,不但要弄懂概念还要学很多新知识(分分钟自闭

你可能感兴趣的:(面向对象程序设计2020第二次作业)