预处理
#pragma warning(disable : 4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STUDENT_NAME_SEX_MAX 20
#define STUDENT_SEX_MAX 5
#define STUDENT_INFORTMATION 20
#define SUBJECT_NUMBER 2
#define LEN sizeof(struct student)
#define PRINT_STUDENT_INFO(student) \
printf(" %d\t %s\t %s\t %s\t %.2f\t %.2f\t %.2f\t %.2f\n", \
(student).num, (student).name, (student).clas, (student).sex, \
(student).Eng_score, (student).C_score, (student).total, (student).aver)
int functionCalled = 0;
菜单
void menu() {
printf("\n\n\n");
printf("\t\t-------------------------------------------------\n");
printf("\t\t|| ---------------- ||\n");
printf("\t\t||**************学生信息管理系统(队列版)*******||\n");
printf("\t\t|| ---------------- ||\n");
printf("\t\t|| ||\n");
printf("\t\t||~~~~~~~~~~~~~~~1.录入学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~2.删除学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~3.修改学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~4.查询学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~5.显示学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~6.排序学生信息~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~7.显示最好成绩~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~8.分组统计成绩~~~~~~~~~~~~~~~~||\n");
printf("\t\t||~~~~~~~~~~~~~~~9.清屏~~~~~~~~~~~~~~~~~~~~~~~~||\n");
printf("\t\t|| ||\n");
printf("\t\t||*********************************************||\n");
}
结构体
typedef struct student {
int num;
char name[STUDENT_NAME_SEX_MAX];
char clas[STUDENT_NAME_SEX_MAX];
char sex[STUDENT_SEX_MAX];
float Eng_score;
float C_score;
float total;
float aver;
} Student;
typedef struct {
Student queue[STUDENT_INFORTMATION];
int front, rear;
} StudentQueue;
主函数
int main() {
StudentQueue queue = { {0} };
Student stu;
memset(&stu, 0, sizeof(stu));
initQueue(&queue);
int countptr = 0;
int* count = &countptr;
menu();
int choice = 0;
printf("请选择功能(1-9):\n");
int num;
float n;
scanf("%d", &choice);
while (choice){
if (choice >= 1 && choice <= 9) {
switch (choice) {
case 1: inStudent(&queue,count);
writeQueueToFile(&queue, "stu.txt");
break;
case 2:
printf("请输入要删除的学生学号:");
scanf("%d", &num);
deleteStudent(&queue,count, num);
break;
case 3:
printf("请输入要修改的学生学号:");
scanf("%d", &num);
updateStudent(&queue,count, num);
break;
case 4:
printf("请输入要查询的学生学号:");
scanf("%d", &num);
selectStudent(&queue,count, num);
break;
case 5: printStudents(&queue,count); break;
case 6: sortStudents(&queue,count); break;
case 7: maxStudent(&queue,count); break;
case 8:
printf("请输入按总成绩分组的值:");
scanf("%f", &n);
cutStudents(&queue,count, n);
break;
case 9: clearScreen(); break;
default: printf("无效的选项,请重新选择。\n");
}
if (choice == 9)menu();
printf("\n");
printf("请选择功能(1-9):");
scanf("%d", &choice);
}
}
return 0;
}
队列操作函数(初始化,判断,入出队,队首)
void initQueue(StudentQueue* q) {
if (q == NULL) return;
q->front = -1;
q->rear = -1;
}
int isEmpty(StudentQueue* q) {
if (q == NULL) return -1;
return q->front == -1;
}
int isFull(StudentQueue* q) {
return q->rear == STUDENT_INFORTMATION - 1;
}
void enqueue(StudentQueue* q, Student student) {
if (isFull(q)) {
printf("Queue is full\n");
return;
}
if (q->rear==-1&&q->front==-1) {
q->rear = 0;
q->front = 0;
q->queue[q->rear] = student;
q->rear++;
}
else if(q->rear>0&&q->rear<STUDENT_INFORTMATION-1){
q->queue[q->rear] = student;
q->rear++;
}else {
printf("Failed to enqueue student due to index out of bounds.\n");
}
}
void dequeue(StudentQueue* q) {
if (isEmpty(q)) {
printf("Queue is empty\n");
return ;
}
PRINT_STUDENT_INFO(q->queue[q->front]);
q->front = (q->front + 1);
}
Student peek(StudentQueue* q) {
if (!isEmpty(q))
return q->queue[q->front];
Student temp = { 0 };
return temp;
}
其他函数原型声明
void printAndDequeue(StudentQueue* q);
void readStudentsFromFile(StudentQueue* q, int* count, const char* filename);
void writeQueueToFile(StudentQueue* q, const char* filename);
void clearQueueContent(StudentQueue* q);
void menu(void);
void inStudent(StudentQueue* q, int* count);
void deleteStudent(StudentQueue* q, int* count, int num);
void updateStudent(StudentQueue* q, int* count, int num);
void selectStudent(StudentQueue* q, int* count, int num);
void printStudents(StudentQueue* q, int* count);
void sortStudents(StudentQueue* q, int* count);
void maxStudent(StudentQueue* q, int* count);
void cutStudents(StudentQueue* q, int* count, float n);
void clearScreen(void);
录入
void inStudent(StudentQueue* q, int* count) {
Student stu;
memset(&stu, 0, sizeof(stu));
char ch[2];
int i;
if(!q)readStudentsFromFile(q, count, "stu.txt");
printf("当前队列中已有 %d 条学生记录。\n", *count);
printf("输入学生信息(y/n);\n");
scanf("%s", ch);
while (strcmp(ch, "y") == 0 || strcmp(ch, "Y") == 0) {
while (getchar() != '\n');
printf("学号: \n");
scanf("%d", &stu.num);
for (i = q->front; i != q->rear; ++i) {
if (q->queue[i].num == stu.num) {
printf("学号已存在,请重新输入。\n");
return;
}
}
printf("姓名: \n");
scanf("%s", &stu.name);
printf("班级: \n");
scanf("%s", &stu.clas);
printf("性别: \n");
scanf("%s", &stu.sex);
printf("英语成绩: \n");
scanf("%f", &stu.Eng_score);
printf("C语言成绩: \n");
scanf("%f", &stu.C_score);
stu.total = stu.Eng_score + stu.C_score;
stu.aver = stu.total / SUBJECT_NUMBER;
if (strcmp(ch, "y") == 0 || strcmp(ch, "Y") == 0)
{
enqueue(q, stu);
(*count)++;
}
printf("是否继续录入学生信息(y/n):");
scanf("%s", ch);
}
}
删除
void deleteStudent(StudentQueue* q,int* count, int num) {
if (*count == 0) {
printf("文件无内容。\n");
return;
}
Student tempStu[STUDENT_INFORTMATION];
int tempIndex = 0;
while (*count) {
if (q->queue[*count].num != num) {
tempStu[tempIndex++] = q->queue[*count];
}
else {
printf("找到学生信息,正在删除...\n");
printf("删除成功!\n");
}
(*count)--;
}
if(*count!=0)printf("无该学生信息\n");
else {
FILE* fp = fopen("stu.txt", "wb");
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < tempIndex; i++) {
fwrite(&tempStu[i], LEN, 1, fp);
}
fclose(fp);
initQueue(q);
for (int i = 0; i < tempIndex; i++) {
enqueue(q, tempStu[i]);
}
}
}
修改
void updateStudent(StudentQueue* q,int*count, int num) {
Student stu;
memset(&stu, 0, sizeof(stu));
if (isEmpty(q)) {
printf("队列为空。\n");
return;
}
int found = 0;
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].num == num) {
found = 1;
stu = q->queue[i];
break;
}
}
if (!found) {
printf("未找到学号为 %d 的学生。\n", num);
return;
}
printf("找到学生信息,请输入要修改的字段(0完成修改):\n");
printf("1: 姓名 2: 班级 3: 性别 4: 英语成绩 5: C语言成绩\n");
int option;
scanf("%d", &option);
while (option) {
switch (option) {
case 1: printf("姓名: "); scanf("%s", &stu.name); break;
case 2: printf("班级: "); scanf("%s", &stu.clas); break;
case 3: printf("性别: "); scanf("%s", &stu.sex); break;
case 4: printf("英语成绩: "); scanf("%f", &stu.Eng_score); break;
case 5: printf("C语言成绩: "); scanf("%f", &stu.C_score); break;
default: printf("无效的选项。\n"); return;
}
stu.total = stu.Eng_score + stu.C_score;
stu.aver = stu.total / SUBJECT_NUMBER;
printf("修改后的信息:\n");
PRINT_STUDENT_INFO(stu);
printf("继续修改其他字段吗(0完成修改)?:");
scanf("%d", &option);
}
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].num == num) {
q->queue[i] = stu;
break;
}
}
printf("学生信息已更新。\n");
}
查询
void selectStudent(StudentQueue* q,int* count, int num) {
if (isEmpty(q)) {
printf("队列为空。\n");
return;
}
int found = 0;
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].num == num) {
found = 1;
printf("找到学生信息:\n");
PRINT_STUDENT_INFO(q->queue[i]);
break;
}
}
if (!found) {
printf("未找到学号为 %d 的学生。\n", num);
}
}
显示
void printStudents(StudentQueue* q,int* count) {
if (isEmpty(q)) {
printf("队列无内容。\n");
return;
}
printf("学号\t姓名\t班级\t性别\t英语成绩\tC语言成绩\t总成绩\t平均成绩\n");
printAndDequeue(q);
}
排序
void sortStudents(StudentQueue* q,int* count) {
readStudentsFromFile(q, count, "stu.txt");
int i, j;
Student temp;
if (isEmpty(q)) {
printf("队列为空。\n");
return;
}
for (i = 0; i < STUDENT_INFORTMATION - 1; i++) {
for (j = 0; j < STUDENT_INFORTMATION - i - 1; j++) {
if (q->queue[j].num > q->queue[j + 1].num) {
temp = q->queue[j];
q->queue[j] = q->queue[j + 1];
q->queue[j + 1] = temp;
}
}
}
printf("排序完成。\n");
printAndDequeue(q);
}
最好成绩
void maxStudent(StudentQueue* q,int* count) {
if (isEmpty(q)) {
printf("队列为空。\n");
return;
}
Student maxStu = q->queue[q->front];
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].total > maxStu.total) {
maxStu = q->queue[i];
}
}
printf("总成绩最高的学生信息:\n");
PRINT_STUDENT_INFO(maxStu);
}
分组统计
void cutStudents(StudentQueue* q,int* count, float n)
{
int above = 0, below = 0;
if (isEmpty(q)) {
printf("队列为空。\n");
return;
}
printf("总成绩大于%.2f的学生:\n", n);
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].total > n) {
PRINT_STUDENT_INFO(q->queue[i]);
above++;
}
}
printf("总成绩小于%.2f的学生:\n", n);
for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
if (q->queue[i].total < n) {
PRINT_STUDENT_INFO(q->queue[i]);
below++;
}
}
printf("大于指定分数的学生有%d人,小于指定分数的学生有%d人。\n", above, below);
}
清屏
void clearScreen() {
system("cls");
}
思考
加入操作,可不可以不重复读取文件数据入队列?
显示操作,从文件获取信息输出
不同模块的共用队列,队列初始化
break,continue,return 效果
队列缓冲区问题
结构体与队列数据处理问题
队列缓存乱加入文件