结对项目

1. GitHub地址:https://github.com/dachai9/team-work.git

结对项目组成员:3218005036陈芝敏,3218005037冯晓凤

2. 题目:实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)。
  • 说明:
    自然数:0, 1, 2, …。
    真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
    运算符:+, −, ×, ÷。
    括号:(, )。
    等号:=。
    分隔符:空格(用于四则运算符和等号前后)。
    算术表达式:
    e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
    其中e, e1和e2为表达式,n为自然数或真分数。
    四则运算题目:e = ,其中e为算术表达式。

  • 需求:

    • 使用 -n 参数控制生成题目的个数,例如
      Myapp.exe -n 10 :将生成10个题目。

    • 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如
      Myapp.exe -r 10
      将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。

    • 生成的题目中计算过程不能产生负数。

    • 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。

    • 每道题目中出现的运算符个数不超过3个。

    • 程序一次运行生成的题目不能重复。 ----未完成

    • 生成的题目存入执行程序的当前目录下的Exercises.txt文件。

    • 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。

    • 程序应能支持一万道题目的生成。

    • 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
      Myapp.exe -e .txt -a .txt

    • 统计结果输出到文件Grade.txt。

3. PSP
PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 40
· Estimate · 估计这个任务需要多少时间 30 40
Development 开发 2030 1910
· Analysis · 需求分析 (包括学习新技术) 15 15
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 (和同事审核设计文档) 5 5
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 30
· Design · 具体设计 90 120
· Coding · 具体编码 1440 870
· Code Review · 代码复审 60 120
· Test · 测试(自我测试,修改代码,提交修改) 360 720
Reporting 报告 250 150
· Test Report · 测试报告 210 120
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 20
合计 2310 2100
4. 设计思路
  • 若flag=1生成整数,flag=0生成分数
  • 使用逆波兰算法进行算式运算(栈)
  • 将整数化成分母为1的分数,就可以只考虑分数的运算
  • 以确定的方式生成随机括号:flag的值表示括号的位置
  • 校对答案时,先生成正确的题目序号文件和错误的题目序号文件,再统一写入Grade文件,然后删掉中间文件
5. 流程图

image

6. 代码实现
  • 主函数
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<windows.h>
#include<time.h>
#include "team-project.cpp"

//exe -n 10 -r 10
//exe -e txt -a txt

int main(int argc, char *argv[]) {
    printf("参数个数%d\n", argc);
    char **func;
    int k=0;
    int amount = 0;
    int limit = 0;
    char *txt_e;
    char *txt_a;

    if(argc != 5) {
        printf("输入参数不正确!\n");
        return 0;
    }

    if(argv[1][1] == 'n') {
        for(int i=2; i<argc; i++) {
            if(i == 2){
                for(int j=0; argv[i][j]!='\0'; j++) {
                    if(argv[i][j] < '0' || argv[i][j] > '9') {
                        printf("传入第二个参数不对!!\n");
                        return 0;
                    }
                    amount *= 10;
                    amount += argv[i][j]-'0';
                }
            }
            if(i==3 && argv[i][1] != 'r') {
                printf("传入第三个参数不对\n");
                return 0;
            }
            if(i == 4) {
                for(int j=0; argv[i][j]!='\0'; j++) {
                    if(argv[i][j] < '0' || argv[i][j] > '9') {
                        printf("传入第四个参数不对!!\n");
                        return 0;
                    }
                    limit *= 10;
                    limit += argv[i][j]-'0';
                }
            }
        }
        buildnum(amount, limit);
    } else if(argv[1][1] == 'e') {
        for(int i=2; i<argc; i++) {
            if(i == 2){
                txt_e = argv[2];
            }
            if(i==3 && argv[i][1] != 'a') {
                printf("传入第三个参数不对\n");
                return 0;
            }
            if(i == 4) {
                txt_a = argv[4];
            }
        }
        Check(txt_e, txt_a);
    }
    return 0;
}
  • 构建式子并计算结果
int buildnum(int num, int range) {
//    int num = 0;      //数量
//    int range = 0;    //范围
    int num2 = 1;
    char *svary1, *svary2, *svary3, *svary4;
    char s1[100]= {},s2[100]= {}, s3[100]= {};
    char a[100] = {};
    char b[20] = {};
    
    srand((unsigned)time(NULL));

    FILE *fp;
    fp = fopen("Exercises.txt", "w");
    if(fp == NULL) {
        printf("Exercises.txt 打不开!");
        return 0;
    }
    // 清空原答案文件
    FILE *fpan;
    if((fpan = fopen("Answers.txt", "w")) == NULL) {
        printf("打开Answers.txt失败!\n");
    }
//    printf("清空成功!\n");
    fclose(fpan);

    for(int i=1; i<=num; i++) {
//        printf("\n%d. ", i);

        //随机个数运算符
        // srand((unsigned)time(NULL));
        num2 = rand() % 3 + 1;
//        num2 = 3;
//        printf("运算符个数:%d\n",num2);
        if(num2 == 1) {
            svary1 = getRandom(range);
            strcpy(s1, svary1);

            char *optor1 = getSignal();
            svary2 = getRandom(range);

            memset(a, 0, sizeof(a));
            constring(a, s1, a);
            constring(a, " ", a);
            constring(a, optor1, a);
            constring(a, " ", a);
            constring(a, svary2, a);
            constring(a, "#", a);

            if(Countarray(a, b) == -1) {
                i--;
                continue;

            }
//            printf("%d. ", i);

            if(optor1 == "/") {
                optor1 = "÷";
            }
//            printf("%s %s %s =\n", s1, optor1, svary2);
            fprintf(fp, "%d%s %s %s %s =\n", i, ".", s1, optor1, svary2);
        }
        if(num2==2) {
            int flag;
            //  srand((unsigned)time(NULL));
            flag = rand() % 3; // 是否生成括号
//            printf("括号位置:%d\n", flag);

            svary1=getRandom(range);
            strcpy(s1, svary1); // 第一个变量

            char *optor1 = getSignal(); // 第一个运算符
//            printf("%s\n",optor1);
            svary2 = getRandom(range);
            strcpy(s2,svary2); // 第二个变量

            char *optor2= getSignal(); // 第二个运算符
//            printf("%s\n",optor1);
//            printf("%s\n",optor2);
            svary3=getRandom(range); // 第三个变量

            memset(a, 0, sizeof(a)); // 初始化a数组

            // flag==1:(a+b)+c
            // flag==2:a+(b+c)
            if(flag == 1) {
                constring(a, "(", a);
            }
            constring(a, s1, a);
            constring(a, " ", a);
            constring(a, optor1, a);
            constring(a, " ", a);
            if(flag == 2) {
                constring(a, "(", a);
            }
            constring(a, s2, a);
            if(flag == 1) {
                constring(a, ")", a);
            }
            constring(a, " ", a);
            constring(a, optor2, a);
            constring(a, " ", a);
            constring(a, svary3, a);
            if(flag == 2) {
                constring(a, ")", a);
            }
            constring(a, "#", a);

//            printf("加入括号后生成:%s\n", a);
            if(Countarray(a, b) == -1) {
//                printf("返回的是-1\n\n");
                i--;
                continue;
            }

            if(optor1 == "/")
                optor1 = "÷";
            if(optor2 == "/")
                optor2 = "÷";
//            printf("(无括号)化成÷后:%s %s %s %s %s =\n", s1, optor1, s2,optor2,svary3);
            if(flag == 1) {
                fprintf(fp, "%d%s %s%s %s %s%s %s %s =\n", i, ".", "(", s1, optor1, s2, ")", optor2, svary3);
            } else if(flag == 2) {
                fprintf(fp, "%d%s %s %s %s%s %s %s%s =\n", i, ".", s1, optor1, "(", s2, optor2, svary3, ")");
            } else {
                fprintf(fp, "%d%s %s %s %s %s %s =\n", i, ".", s1, optor1, s2, optor2, svary3);
            }
        }
        if(num2 == 3) {
            int flag;
            //  srand((unsigned)time(NULL));
            flag = rand() % 5 + 1; // 是否生成括号
//            printf("括号位置:%d\n", flag);
            svary1=getRandom(range);
            strcpy(s1, svary1); // 第一个变量

            char *optor1 = getSignal();
//            printf("optor1 = %s\n",optor1); // 第一个运算符

            svary2 = getRandom(range);
            strcpy(s2,svary2); // 第二个变量

            char *optor2= getSignal();
//            printf("optor2 = %s\n",optor2); // 第二个运算符

            svary3=getRandom(range); // 第三个变量
            strcpy(s3, svary3);

            char *optor3= getSignal();
//            printf("optor3 = %s\n",optor3); // 第三个运算符

            svary4=getRandom(range); // 第四个变量

            memset(a, 0, sizeof(a)); // 初始化a数组
            // printf("1\n");

            // flag==1: (a+b)+c+d
            // flag==2: a+(b+c)+d
            // flag==3: a+b+(c+d)
            // flag==4: (a+b+c)+d
            // flag==5: a+(b+c+d)
            if(flag == 1 || flag == 4) {
                constring(a, "(", a);
            }
            constring(a, s1, a);
            constring(a, " ", a);
            constring(a, optor1, a);
            constring(a, " ", a);
            if(flag == 2 || flag == 5) {
                constring(a, "(", a);
            }
            constring(a, s2, a);
            if(flag == 1) {
                constring(a, ")", a);
            }
            constring(a, " ", a);
            constring(a, optor2, a);
            constring(a, " ", a);
            if(flag == 3) {
                constring(a, "(", a);
            }
            constring(a, s3, a);
            if(flag == 2 || flag == 4) {
                constring(a, ")", a);
            }
            constring(a, " ", a);
            constring(a, optor3, a);
            constring(a, " ", a);
            constring(a, svary4, a);
            if(flag == 3 || flag == 5) {
                constring(a, ")", a);
            }
            constring(a, "#", a);

//            printf("加入括号后生成:%s\n", a);
            if(Countarray(a, b) == -1) {
//                printf("返回的是-1\n\n");
                i--;
                continue;
            }
            //将/转换为÷
            if(optor1 == "/")
                optor1 = "÷";
            if(optor2 == "/")
                optor2 = "÷";
            if(optor3 == "/")
                optor3 = "÷";

//            printf("(无括号)化成÷后:%s %s %s %s %s %s %s=\n", s1, optor1, s2, optor2, s3, optor3, svary4);
            if(flag == 1) {
                fprintf(fp, "%d%s %s%s %s %s%s %s %s %s %s =\n", i, ".", "(", s1, optor1, s2, ")", optor2, s3, optor3, svary4);
            } else if(flag == 2) {
                fprintf(fp, "%d%s %s %s %s%s %s %s%s %s %s =\n", i, ".", s1, optor1, "(", s2, optor2, s3, ")", optor3, svary4);
            } else if(flag == 3) {
                fprintf(fp, "%d%s %s %s %s %s %s%s %s %s%s =\n", i, ".", s1, optor1, s2, optor2, "(", s3, optor3, svary4, ")");
            } else if(flag == 4) {
                fprintf(fp, "%d%s %s%s %s %s %s %s%s %s %s =\n", i, ".", "(", s1, optor1, s2, optor2, s3, ")", optor3, svary4);
            } else if(flag == 5) {
                fprintf(fp, "%d%s %s %s %s%s %s %s %s %s%s =\n", i, ".", s1, optor1, "(", s2, optor2, s3, optor3, svary4, ")");
            } else {
                fprintf(fp, "%d%s %s %s %s %s %s %s %s=\n", i, ".", s1, optor1, s2, optor2, s3, optor3, svary4);
            }

        }
//        printf("生成成功!\n");
        FILE *fp_a;
        if((fp_a = fopen("Answers.txt", "a+")) == NULL) {
            printf("打开Answers.txt失败!\n");
        }
        fprintf(fp_a, "%s\n", b);
        memset(b, 0, sizeof(b));
        fclose(fp_a);
    }
    fclose(fp);
    printf("题目写入Exercises.txt文件成功!\n");
    printf("答案写入Answers.txt文件成功!\n");
//    printf("上传成功!\n");
    return 0;
}
  • 生成变量
char *getRandom(int range) {
  int flag;
  char svary[10];
  // srand((unsigned)time(NULL));
  flag = rand() % 2;  //是否生成分数
//    printf("flag = %d\n", flag);
  if(flag == 1) {
      return getzhenRandom(range);
  } else {
      return getfenRandom(range);
  }
}
  • 生成整数
char *getzhenRandom(int range) {
  int vary;
  char *svary;
  //srand((unsigned)time(NULL));
  vary = rand() % range + 1;
  itoa(vary, svary, 10);

  return svary;
}
  • 生成分数
char *getfenRandom(int range) {
  char *a;
  memset(a, 0, sizeof(a));
  int md1, md2, num1, num2;
  do {
      // srand((unsigned)time(NULL));
      num2 = rand() % range + 1;//分母
      // srand((unsigned)time(NULL));
      num1 = rand() % range*num2 + 1;//分子
      while(num2 == 0) {
          // srand((unsigned)time(NULL));
          num2 = rand() % range +1;
      }
      // 前面的带分数
      md1 = num1/num2;

      // 处理后的分子
      md2 = num1%num2;
  } while(md2 == 0);

  char smd1[100] = {};
  char smd2[100] = {};
  char snum2[100] = {};
  itoa(md1, smd1, 10);
  itoa(md2, smd2, 10);
  itoa(num2, snum2, 10);
  // 如果前面的带分数等于0就不要显示”'“
  if(md1 != 0) {
      strcat(a, smd1);
      strcat(a, "'");
  }
  strcat(a, smd2);
  strcat(a, "/");
  strcat(a, snum2);
  return a;
}
  • 生成运算符
char *getSignal() {
  int opnum = 0;
  char *optor;
  //运算符生成
  //srand((unsigned)time(NULL));
  opnum = rand() % 4;
  switch (opnum) {
  case 0:
      optor = "+";
      break;
  case 1:
      optor = "-";
      break;
  case 2:
      optor = "*";
      break;
  case 3:
      optor = "/";
      break;
  default:
      break;
  }
  return optor;
}
  • 逆波兰算法
//单行计算结果
int Countarray(char *str, char b[]) {
//    char str[MAX];
  memset(b, 0, sizeof(b));
//    printf("传入的计算题:");
//    printf("%s\n", str);
  int i=0, value=0, flag=0,val_f=0,val_m=0;
  int old_ope;
  Stack *f_numstack,*m_numstack, *opestack;//分别为分子,分母,运算符的栈
  f_numstack = Createstack();
  m_numstack = Createstack();
  opestack = Createstack();
  while(str[i] != '#') {
      if(str[i] == ' ') {
          i++;
          continue;
      }
      if(str[i] >= '0' && str[i] <= '9') {
          value *= 10;
          value += str[i] - '0';
          flag = 1;
      } else {
          // 处理带分数
          if(str[i]=='\'') {
              i++;
              int value1[2]= {};
              memset(value1, 0, sizeof(value1)); // 初始化value1数组
              int j=0;

              while(str[i]!=' ' && str[i]!='#' && str[i]!=')') {
                  if(str[i]=='/') {
                      j=1;
                      i++;
                      continue;
                  }
                  value1[j] *= 10;
                  value1[j] += str[i] - '0';
                  i++;
              }
              value1[0]+=value*value1[1];
              // 分子分母入栈
//                printf("\tvalue1[0] = %d\n\tvalue1[1] = %d\n", value1[0], value1[1]);
              to_f(f_numstack,m_numstack,value1[0],value1[1]);
              flag=0;
              value=0;
              if(str[i]=='#') {
                  break;
              }
              if(str[i] == ')')
                  i--;
              i++;
          }
          if(flag) {
              to_f(f_numstack,m_numstack,value,1);
              flag = 0;
              value = 0;
          }
          // 直接结束计算
          if(str[i]=='#') {
              break;
          }
          if(str[i] == ')') {
              if(Right(f_numstack,m_numstack, opestack)==-1)
                  return -1;//右括号
          } else {
              if(Dealope(f_numstack,m_numstack, opestack, str[i]) == -1)
                  return -1;//其他符号
          }
      }
      i++;
  }
  if(flag) {
      // value是整数
      to_f(f_numstack,m_numstack,value,1);
  }
  while(!Empty(opestack)) {
      Pop(opestack, &old_ope);
      // 消除负数情况
      if(Calculation(f_numstack,m_numstack, old_ope) == -1)
          return -1;
  }
  Pop(f_numstack, &val_f);
  Pop(m_numstack,&val_m);
  // 存储化简后的结果
//    char b[100] = {};
  easy(val_f, val_m, b);
//    printf("b=%s\n",b);
//    printf("1\n");
//    printf("%s = %s\n\n", str, b);
  return 0;
}
  • 分子分母分别入栈
void to_f(Stack *f_numstack,Stack *m_numstack,int value1,int value2) {
  Push(f_numstack,value1);
  Push(m_numstack,value2);
}
  • 设置运算符优先级
//符号优先级
int Priority(char ope) {
  switch(ope) {
  case '(':
      return 0; // 左括号已经在栈内,如果比较,则其优先级最低
  case '+':
  case '-':
      return 1;
  case '*':
  case '/':
      return 2;
  default:
      return -1;
  }
}
  • 计算
int Calculation(Stack *f_numstack,Stack *m_numstack, int ope) {
  int sum1 = 0, sum2 = 0, n_f1, n_f2, n_m1, n_m2;
  Pop(f_numstack, &n_f2);
  Pop(m_numstack,&n_m2);
  Pop(f_numstack,&n_f1);
  Pop(m_numstack, &n_m1);
//    printf("n_f2=%d,n_m2=%d,n_f1=%d,n_m1=%d\n",n_f2,n_m2,n_f1,n_m1);

  switch(ope) {
  case '+':
      if(n_f2==0) {
          sum1=n_f1;
          sum2=n_m1;
      } else if(n_f1==0) {
          sum1=n_f2;
          sum2=n_m2;
      } else {
          sum2=beishu(n_m1,n_m2);
          n_f1=sum2/n_m1*n_f1;
          n_f2=sum2/n_m2*n_f2;
          sum1=n_f1+n_f2;
      }
      break;
  case '-':
      if(n_f1==0&&n_f2!=0)
          return -1;
      else if(n_f1!=0&&n_f2==0) {
          sum1=n_f1;
          sum2=n_m1;
      } else if(n_f1==0&&n_f2==0) {
          sum1=0;
          sum2=1;
      } else {
          sum2=beishu(n_m1,n_m2);
          n_f1=(sum2/n_m1)*n_f1;
          n_f2=(sum2/n_m2)*n_f2;
          sum1=n_f1-n_f2;
//            printf("sum1=%d, sum2=%d\n",sum1,sum2);
          if(sum1<0) {
//                printf("return -1;\n");
              return -1;
          }else if(sum1==0) {
              sum1=0;
              sum2=1;
          }
      }
      break;
  case '*':
      if(n_f1==0||n_f2==0) {
          sum1=0;
          sum2=1;
      }
      sum1=n_f1*n_f2;
      sum2=n_m1*n_m2;
      break;
  case '/':
      if(n_f2==0)
          return -1;
      else if(n_f1==0&&n_f2!=0) {
          sum1=0;
          sum2=1;
      } else {
          sum1=n_f1*n_m2;
          sum2=n_f2*n_m1;
      }
      break;
  default:
      break;
  }
//    printf("sum1=%d,sum2=%d\n", sum1,sum2);
  Push(f_numstack, sum1);
  Push(m_numstack, sum2);
}
  • 运算符处理
//处理除右括号外的符号
int Dealope(Stack *f_numstack,Stack *m_numstack, Stack *opestack, int ope) {
  int old_ope;
  if(Empty(opestack) || ope == '(') {
      Push(opestack, ope);
      return 0;
  }
  Top(opestack, &old_ope);
//    printf("old_ope = %c\tope = %c\n", old_ope, ope);
  if(Priority(ope) > Priority(old_ope)) {
      Push(opestack, ope);
      return 0;
  }
  while(Priority(ope) <= Priority(old_ope)) {
      Pop(opestack, &old_ope);
      if(Calculation(f_numstack,m_numstack, old_ope) == -1)
          return -1;
      if(Empty(opestack))
          break;
      Top(opestack, &old_ope);
  }
  Push(opestack, ope);
  return 0;
}

//右括号
int Right(Stack *f_numstack,Stack *m_numstack, Stack *opestack) {
  int old_ope;
  Top(opestack, &old_ope);
  while(old_ope != '(') {
      Pop(opestack, &old_ope);
      if(Calculation(f_numstack,m_numstack, old_ope) == -1)
          return -1;
      Top(opestack, &old_ope);
  }
  Pop(opestack, &old_ope);//去掉左括号
  return 0;
}
  • 最后式子的化简
//化简
char *easy(int val_f,int val_m,char a[]) {
  char str0[100] = {};
  char str1[100] = {};
  char str2[100] = {};
  int n1,n2;
  int n3;
  if(val_f == 0) {
      a[0] = '0';
//        printf("a=%s\n",a);
      return 0;
  }
  n1=val_f/val_m;
  n2=val_f%val_m;
//    printf("n1 = %d, n2 = %d\n", n1, n2);
  if(n1==0) {
      if(n2!=0) {
          n3 = gcd(val_f,val_m);
          n1 = val_f/n3; // 化简后的分子
          n2 = val_m/n3; // 化简后的分母
//            printf("\nn1 = %d, n2 = %d, n3 = %d\n", n1, n2, n3);
          itoa(n1,str1,10);
          itoa(n2,str2,10);
          constring(str1,"/",a);
          constring(a,str2,a);
      }
      a[0] = '0';
  } else {
      if(n2==0) {
          itoa(n1,str0,10);
          constring(a,str0,a);
      } else {
          n3 = gcd(n2,val_m);
          n2/=n3;
          val_m/=n3;
          itoa(n1,str1,10);
          itoa(n2,str2,10);
          itoa(val_m,str0,10);

          constring(str1,"'",a);
          constring(a,str2,a);
          constring(a,"/",a);
          constring(a,str0,a);
      }
  }
  return 0;
}
  • 校对函数
void Check(char *exer, char *answer) {
    printf("传入的文件名:%s  %s\n", exer, answer);
    FILE *fp_e, *fp_a, *fp_c, *fp_r, *fp_w;
    fp_e = fopen(exer, "r");
    fp_a = fopen(answer, "r");
    fp_c = fopen("Grade.txt", "w+");
    fp_r = fopen("Right.txt", "w+");
    fp_w = fopen("Wrong.txt", "w+");

    if(fp_e == NULL || fp_a == NULL || fp_c == NULL || fp_r == NULL || fp_w == NULL) {
        printf("读取文件失败!\n");
        return ;
    }
    char a[50]; // 获取题目
    char a_b[50];
    char b[50]; // 获取正确答案
    memset(a,0,sizeof(a));
    memset(a_b,0,sizeof(a_b));
    memset(b,0,sizeof(b));
    char getc_r, getc_w;
    int i=0, r_num=0, w_num=0;

    while(!feof(fp_e)){
        i++;
        if(Expression(a, fp_e, a_b) == -1) break;
        fscanf(fp_a,"%s",b);
        if(strcmp(a_b, b) == 0) {
            r_num++;
            fprintf(fp_r, ",%d", i);
        }
        else {
            w_num++;
            fprintf(fp_w, ",%d", i);
        }
        memset(a,0,sizeof(a));
        memset(a_b,0,sizeof(a_b));
        memset(b,0,sizeof(b));
    }
    // 写入文件
    rewind(fp_r);
    rewind(fp_w);
    getc_r = fgetc(fp_r);
    getc_w = fgetc(fp_w);

    fprintf(fp_c, "%s%d%s", "Correct: ", r_num, "(");
    while(getc_r != EOF && getc_r != ' ') {
        if(getc_r == ' ') break;
        getc_r = fgetc(fp_r);
        fprintf(fp_c, "%c", getc_r);
//        if(getc_r == ' ') break;
    }
    fprintf(fp_c, "%s%s%s%d%s", ")", "\n", "Wrong: ", w_num, "(");
//        fscanf(fp_w, "%s", gets_w);
    while(getc_w != EOF && getc_w != ' ') {
        if(getc_w == ' ') break;
        getc_w = fgetc(fp_w);
        fprintf(fp_c, "%c", getc_w);
//        if(getc_w == ' ') break;
    }
    fprintf(fp_c, "%s", ")");

    fclose(fp_a);
    fclose(fp_e);
    fclose(fp_r);
    fclose(fp_w);
    if(remove("Right.txt") == -1) {
        printf("删除Right.txt文件失败!\n");
    }
    if(remove("Wrong.txt") == -1) {
        printf("删除Wrong.txt文件失败!\n");
    }
    printf("校对结束!!!\n");
    printf("校对结果存入Grade.txt文件成功!\n");
}
  • 从文件读取并制作式子
int Expression(char a[], FILE *fp, char b[]) {
  char x[MAX];
  char y[MAX];
  char z1[MAX] = {"÷"};
  char z2[MAX] = {"="};
  int i=0,j=0,k=0;
  memset(x,0,sizeof(x));
  memset(y,0,sizeof(y));
//    x[0]=fgetc(fp);
//    printf("x[0]=%c ",x[0]);
//        while(x[i] != '\n' && x[i]!=EOF) {
//        x[++i] = fgetc(fp);
//        printf("x[i]=%c ",x[i]); // 1+2 = #
//    }
  fscanf(fp,"%s",y);
  while(strcmp(y,z2) != 0) {
      if(feof(fp))
          return -1;
      if(strcmp(y,z2) == 0)
          break;
      if(strcmp(y,z1) == 0)
          constring(x,"/",x);
      else
          constring(x,y,x);
      memset(y,0,sizeof(y));
      constring(x, " ", x);
      fscanf(fp,"%s",y);
  }
  constring(x, "\n", x);
  for(k=0; x[k] != '.'; k++);
  for(i=k+1; x[i]!='\n'; i++) {
      if(x[i] == '=')
          break;
      a[j] = x[i];
      j++;
  }
  a[j] = '#';
  Countarray(a, b);
  return 0;
}
7. 测试运行

image
image

// 全对的情况

image

// 改掉最后三个的情况

image

8. 项目小结

遇到的难题和解决方法:

  1. 遇到一个printf删掉之后会出现bug!???; 解决方法:让他冷静几天之后再删掉就可以了(不知道为什么!!)
  2. 在最初计算时只能计算成小数,如果从小数转换成分数会有精度损失; 解决方法:把整数换成分数,把一个数字栈换成分子栈分母栈
  3. 因为用了 ÷ 符号是字符串,所以在文件进行fgetc时会有bug; 解决方法:使用fscanf
  4. 当fscanf取到 ÷ 时无法直接与 “÷” 判断是否相等; 解决方法:使用数组char z1[MAX] = {"÷"}进行数组间判断
  5. 等等等等等
  • 陈芝敏:在本次结对项目里面,我解锁了很多思考方式和逻辑能力,对分数的计算过程加深了理解。这次是第一次和别人一起完成一个项目,稍微感觉到了团队协作的魅力,因为我们是一起打码一起debug,在面对问题有时会出现多种解法,所以这也让我跳出自己的往常的思维方式,以别的角度思考问题。
    partner的闪光点:逻辑思维能力很强!会督促:赶紧来打码啦!!!找bug能力也很👍!

  • 冯晓凤:在这次结对项目中我学习到很多东西,这跟个人项目不一样。在做结对项目的时候,因为要跟队友交流,我可以在这个过程中,可以了解到不一样的想法,学习到不一样的思维方式,可以更深刻地理解题目。一起合作,可以节省时间,毕竟多了一份力,解决问题的时候也可以更快。一起合作还可以相互督促学习。
    陈芝敏同学闪光点:温柔,细心,在我打代码的时候总是发现我一些粗心的错误。在分析设计的时候,思路清晰,总是能提点到我。对与C语言的一些函数了解比较多。 在设计的过程中想法丰富,有建设性。在debug的时候,能够很快发现问题的所在。是一个超级无敌可爱的少女。

posted @ 2020-04-14 22:49  大柴bdhc  阅读(169)  评论(0编辑  收藏  举报