使用C语言写一个程序,小学数学学习系统 具有随机出题、自动评分、查看正确答案、错题重做等功能的测试系统。 [设计要求] (1)设计程序运行界面 (2)用户登录功能 (3)能用菜单选择测试系统的各功能
时间: 2024-03-12 16:44:11 浏览: 20
好的,下面是一个简单的C语言程序,可以实现小学数学学习系统的基本功能。程序使用控制台界面,包括用户登录、随机出题、自动评分、查看正确答案、错题重做等功能。请参考如下代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_QUESTION 10 // 最大题目数量
#define QUESTION_FILE "question.txt" // 题目文件
#define SCORE_FILE "score.txt" // 分数文件
#define USER_FILE "user.txt" // 用户文件
// 题目结构体
typedef struct {
int id; // 题目编号
char content[100]; // 题目内容
char options[4][20]; // 选项
int answer; // 正确答案
} Question;
// 用户结构体
typedef struct {
char username[20]; // 用户名
char password[20]; // 密码
int score; // 分数
} User;
// 用户登录函数
User* login() {
User* user = (User*)malloc(sizeof(User));
printf("请输入用户名:");
scanf("%s", user->username);
printf("请输入密码:");
scanf("%s", user->password);
FILE* fp = fopen(USER_FILE, "r");
if (fp == NULL) {
printf("用户文件读取失败!\n");
return NULL;
}
User temp;
while (fread(&temp, sizeof(User), 1, fp) == 1) {
if (strcmp(user->username, temp.username) == 0 && strcmp(user->password, temp.password) == 0) {
user->score = temp.score;
fclose(fp);
return user;
}
}
printf("用户名或密码错误!\n");
fclose(fp);
return NULL;
}
// 保存用户分数
void save_score(User* user) {
FILE* fp = fopen(USER_FILE, "r+");
if (fp == NULL) {
printf("用户文件读取失败!\n");
return;
}
User temp;
while (fread(&temp, sizeof(User), 1, fp) == 1) {
if (strcmp(user->username, temp.username) == 0) {
temp.score = user->score;
fseek(fp, -sizeof(User), SEEK_CUR);
fwrite(&temp, sizeof(User), 1, fp);
fclose(fp);
return;
}
}
printf("用户不存在!\n");
fclose(fp);
}
// 读取题目文件
Question* read_questions(int* count) {
FILE* fp = fopen(QUESTION_FILE, "r");
if (fp == NULL) {
printf("题目文件读取失败!\n");
return NULL;
}
Question* questions = (Question*)malloc(MAX_QUESTION * sizeof(Question));
*count = 0;
Question temp;
while (fread(&temp, sizeof(Question), 1, fp) == 1) {
questions[*count] = temp;
(*count)++;
}
fclose(fp);
return questions;
}
// 随机出题
void generate_questions(Question* questions, int count, Question* test, int test_count) {
int* used = (int*)malloc(count * sizeof(int));
memset(used, 0, count * sizeof(int));
srand(time(NULL));
for (int i = 0; i < test_count; i++) {
int index;
do {
index = rand() % count;
} while (used[index] == 1);
used[index] = 1;
test[i] = questions[index];
}
free(used);
}
// 评分
void score_test(Question* test, int test_count, User* user) {
int score = 0;
for (int i = 0; i < test_count; i++) {
printf("第%d题:%s\n", i + 1, test[i].content);
for (int j = 0; j < 4; j++) {
printf("%c.%s ", 'A' + j, test[i].options[j]);
}
printf("\n请选择答案:");
char answer;
scanf(" %c", &answer);
if (answer == 'A' + test[i].answer) {
printf("回答正确!\n");
score++;
} else {
printf("回答错误!正确答案为%c\n", 'A' + test[i].answer);
}
}
user->score += score;
printf("本次得分:%d,总分:%d\n", score, user->score);
save_score(user);
}
// 查看正确答案
void show_answers(Question* test, int test_count) {
for (int i = 0; i < test_count; i++) {
printf("第%d题:%s\n", i + 1, test[i].content);
for (int j = 0; j < 4; j++) {
printf("%c.%s ", 'A' + j, test[i].options[j]);
}
printf("正确答案:%c\n", 'A' + test[i].answer);
}
}
// 错题重做
void retry(Question* test, int test_count) {
Question* wrong = (Question*)malloc(test_count * sizeof(Question));
int wrong_count = 0;
for (int i = 0; i < test_count; i++) {
printf("第%d题:%s\n", i + 1, test[i].content);
for (int j = 0; j < 4; j++) {
printf("%c.%s ", 'A' + j, test[i].options[j]);
}
printf("\n请选择答案:");
char answer;
scanf(" %c", &answer);
if (answer == 'A' + test[i].answer) {
printf("回答正确!\n");
} else {
printf("回答错误!正确答案为%c\n", 'A' + test[i].answer);
wrong[wrong_count] = test[i];
wrong_count++;
}
}
if (wrong_count > 0) {
printf("您答错了%d道题,现在为您重做。\n", wrong_count);
score_test(wrong, wrong_count, NULL);
} else {
printf("您本次测试全部正确,无需重做!\n");
}
free(wrong);
}
// 主函数
int main() {
User* user = NULL;
while (user == NULL) {
user = login();
}
int choice;
do {
printf("请选择功能:\n");
printf("1. 开始测试\n");
printf("2. 查看分数\n");
printf("3. 查看正确答案\n");
printf("4. 错题重做\n");
printf("5. 退出\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice) {
case 1: {
int count;
Question* questions = read_questions(&count);
if (questions == NULL) {
break;
}
Question test[MAX_QUESTION];
printf("请输入测试题目数量(最多%d道):", MAX_QUESTION);
int test_count;
scanf("%d", &test_count);
if (test_count > count) {
test_count = count;
}
generate_questions(questions, count, test, test_count);
score_test(test, test_count, user);
free(questions);
break;
}
case 2: {
printf("您的总分为%d分。\n", user->score);
break;
}
case 3: {
int count;
Question* questions = read_questions(&count);
if (questions == NULL) {
break;
}
Question test[MAX_QUESTION];
printf("请输入测试题目数量(最多%d道):", MAX_QUESTION);
int test_count;
scanf("%d", &test_count);
if (test_count > count) {
test_count = count;
}
generate_questions(questions, count, test, test_count);
show_answers(test, test_count);
free(questions);
break;
}
case 4: {
int count;
Question* questions = read_questions(&count);
if (questions == NULL) {
break;
}
Question test[MAX_QUESTION];
printf("请输入测试题目数量(最多%d道):", MAX_QUESTION);
int test_count;
scanf("%d", &test_count);
if (test_count > count) {
test_count = count;
}
generate_questions(questions, count, test, test_count);
retry(test, test_count);
free(questions);
break;
}
case 5: {
printf("谢谢使用,再见!\n");
break;
}
default: {
printf("无效选择,请重新选择!\n");
break;
}
}
} while (choice != 5);
free(user);
return 0;
}
```
上述程序使用了结构体来管理题目和用户信息。题目和用户信息均使用文件存储,分别为QUESTION_FILE、SCORE_FILE和USER_FILE。程序使用随机数来随机出题,使用scanf函数来获取用户输入。程序使用了动态内存分配来管理内存,使用了文件操作函数来读取和保存数据。程序使用了switch-case语句来实现菜单选择功能。程序使用了函数来实现不同的功能,使代码更加模块化和易于维护。