结对作业

| 这个作业属于哪个课程 | 软件工程 |

| ----------------- |--------------- |

| 这个作业要求在哪里| https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/homework/13137 |

| 这个作业的目标 | 实现一个自动生成小学四则运算题目的命令行程序 |
姓名:李轶澍
学号:3122004615
github地址:https://github.com/Gloaming-paladin/calculator/blob/main/calculator

程序代码

define _CRT_SECURE_NO_WARNINGS

include <stdio.h>

include <stdlib.h>

include <string.h>

include <time.h>

include <math.h>

define MAX_EXERCISE_NUM 10000

define MAX_EXERCISE_LEN 100

define MAX_ANSWER_LEN 100

int exer_num;
char exercises[MAX_EXERCISE_NUM][MAX_EXERCISE_LEN];
char answers[MAX_EXERCISE_NUM][MAX_ANSWER_LEN];

void generate_exercise(int r) {
int i, j, k;
char temp[MAX_EXERCISE_LEN];
srand(time(NULL));
for (i = 0; i < exer_num; i++) {
memset(temp, 0, MAX_EXERCISE_LEN);
k = 0;
if (rand() % 2 == 0) {
int num = rand() % r + 1;
sprintf(temp + k, "%d", num);
k += strlen(temp + k);
}
else {
int numerator = rand() % r + 1;
int denominator = rand() % r + 1;
if (numerator > denominator) {
int t = numerator;
numerator = denominator;
denominator = t;
}
sprintf(temp + k, "%d/%d", numerator, denominator);
k += strlen(temp + k);
}
for (j = 0; j < 3; j++) {
char op = '+';
if (rand() % 2 == 0) {
op = '-';
}
else if (rand() % 2 == 0) {
op = '';
}
else {
op = '/';
}
sprintf(temp + k, "%c", op);
k += strlen(temp + k);
}
if (rand() % 2 == 0) {
sprintf(temp + k, "(");
k += strlen(temp + k);
}
for (j = 0; j < 3; j++) {
char op = '+';
if (rand() % 2 == 0) {
op = '-';
}
else if (rand() % 2 == 0) {
op = '
';
}
else {
op = '/';
}
sprintf(temp + k, "%c", op);
k += strlen(temp + k);
}
if (rand() % 2 == 0) {
sprintf(temp + k, ")");
k += strlen(temp + k);
}
exercises[i][0] = '\0';
strcat(exercises[i], temp);
strcat(exercises[i], " = ");
double ans = 0.0; // 使用浮点数来保存答案
if (strstr(temp, "/") != NULL) {
char* p = strtok(temp, "/");
ans = atof(p) / atof(strtok(NULL, "/"));
}
else {
char* p = strtok(temp, "+-");
ans = atof(p); // 使用 atof 函数将字符串转换为浮点数
for (j = 0; j < 3; j++) {
p = strtok(NULL, "+-");
ans = ans + atof(p); // 使用 atof 函数将字符串转换为浮点数
}
}
sprintf(answers[i], "%lf", ans);
}
}

void check_answer() {
int i = 0;
double user_ans; // 保存用户的答案
FILE* fp1, * fp2;
double ans;
fp1 = fopen("Exercises.txt", "r");
fp2 = fopen("Answers.txt", "r");
if (fp1 == NULL || fp2 == NULL) {
printf("Error: cannot open file.\n");
return;
}
while (!feof(fp1)) {
fscanf(fp1, "%s", exercises[i]);
fscanf(fp2, "%s", answers[i]);
ans = atof(answers[i]);
printf("%s ", exercises[i]);
printf("Enter your answer: "); // 提示用户输入答案
scanf("%lf", &user_ans); // 读取用户输入的答案
if (fabs(ans - user_ans) < 0.0001) { // 使用 fabs 函数判断两个浮点数是否相等
printf("Correct\n");
}
else {
printf("Wrong\n");
}
i++;
}
fclose(fp1);
fclose(fp2);
}

int main(int argc, char* argv[]) {
int i;
if (argc < 3) {
printf("Usage: ./exercise -n -r \n");
return 1;
}
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-n") == 0) {
exer_num = atoi(argv[i + 1]);
}
else if (strcmp(argv[i], "-r") == 0) {
int r = atoi(argv[i + 1]);
if (r <= 0) {
printf("Error: range must be a positive integer.\n");
return 1;
}
generate_exercise(r);
break;
}
else {
printf("Error: unknown option.\n");
return 1;
}
}
check_answer();
return 0;
}

代码思路
头文件引入和宏定义:开始时引入必要的头文件,并定义了一些常量和宏,如最大练习数、最大练习长度等。

全局变量声明:声明了一些全局变量,包括练习数量、练习题目数组和答案数组。

生成练习函数:generate_exercise(int r)函数用于生成随机的算术练习题。它通过随机数生成数字和运算符,并将其组合成算术表达式。然后计算正确答案,并将题目和答案保存到全局数组中。

检查答案函数:check_answer()函数负责读取用户输入的答案,并与正确答案进行比较。它从文件中读取题目和答案,然后逐一显示给用户,等待用户输入答案,最后给出判断。

主函数:在main()函数中,程序首先检查命令行参数以获取练习题数量和数值范围。然后根据给定的范围调用generate_exercise()函数生成相应数量的练习题。接着调用check_answer()函数让用户回答问题,并给出反馈。

整体设计思路是:通过随机数生成算术题目,计算出正确答案并保存,在程序运行时读取用户输入的答案并与正确答案比较,最后给出用户答案的判断。

项目小结与心得
清晰的目标和需求分析:在开始编写代码之前,明确了程序的目标和需求,即生成算术练习题并检查用户答案的正确性。这有助于在编码过程中保持方向性和专注性。
模块化设计:将程序分解为几个模块或函数,每个模块负责一个特定的功能。这样做有助于代码的组织和维护,提高了可读性和可维护性。
合理使用数据结构:选择合适的数据结构来存储数据,例如使用二维数组存储练习题和答案。这样可以方便地对数据进行操作和管理。
充分利用标准库函数:在编写代码时,充分利用标准库提供的函数和工具,如stdio.h中的文件操作函数、字符串处理函数等。这样可以减少重复造轮子的工作,提高开发效率。
错误处理和异常情况考虑:考虑到程序可能出现的异常情况,如文件打开失败、命令行参数错误等,编写了相应的错误处理代码,以提高程序的健壮性和稳定性。
测试和调试:在编写代码的过程中,进行了反复的测试和调试,确保程序的功能和逻辑正确。通过测试可以发现并解决潜在的问题,保证程序的质量。
注释和文档:在关键代码部分添加了注释,说明了代码的作用和实现原理。同时,编写了程序的使用说明,使其他人能够更容易地理解和使用这段代码。
总的来说,设计程序需要考虑到各个方面的因素,包括功能需求、模块设计、数据结构选择、错误处理等。通过合理的设计和实现,可以开发出高质量、稳定可靠的软件。

posted @ 2024-03-26 13:21  困于无风之地  阅读(9)  评论(0编辑  收藏  举报