C小项目 —— 学生信息管理系统

时间:2022-06-29 19:06:00
C小项目 —— 学生信息管理系统
实现功能: 1. 录入学生信息
2. 显示所有学生信息
3. 按学号查询学生信息
4. 按姓名查询学生信息(支持模糊查询)
5. 按年龄查询学生信息
6. 修改学生信息
7. 删除学生信息
8. 保存学生信息到文件
9. 从文件载入学生信息
10. 退出系统         使用链表的方式,实现细节很简单,就是链表的一些基本操作(创建,删除结点,增加结点,查找结点等);还有很多地方是可以拓展的(比如使用排序按学号顺序打印,或者按分数高低打印等);使用的是codeblock编译器。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

#define STUDENT_NUMBER 20 // 学号最长20
#define STUDENT_NAME 20 // 姓名最长20
#define STUDENT_SUBJECT 3 // 假设只有三科
#define FILENAME_SIZE 100 // 待保存的文件路径

typedef struct student
{
char num[STUDENT_NUMBER]; /* 学号 */
char name[STUDENT_NAME]; /* 姓名 */
char sex; /* 性别,'1'->男, '0'->女 */
uint8_t age; /* 年龄 */
uint8_t score[STUDENT_SUBJECT]; /* 三科的成绩 */
uint16_t sum; /* 总成绩 */
struct student *next;
} student_t;

student_t *head = NULL;
static uint32_t count = 1; // 系统中学生个数

void menu()
{
printf("\n=========学生信息管理系统========\n");
printf("1. 录入学生信息\n");
printf("2. 显示所有学生信息\n");
printf("3. 按学号查询学生信息\n");
printf("4. 按姓名查询学生信息(支持模糊查询)\n");
printf("5. 按年龄查询学生信息\n");
printf("6. 修改学生信息\n");
printf("7. 删除学生信息\n");
printf("8. 保存学生信息到文件\n");
printf("9. 从文件载入学生信息\n");
printf("10. 退出系统\n");
}

// 录入学生信息:初始化链表和加入链表的过程
void create(void)
{
int i, flag = 0;
char tmp[10];
student_t *point, *q;
while(1)
{
if(1 != count)
{
printf("是否继续录入(y/n):");
gets(tmp);
if(strlen(tmp) > 10)
{
break;
}
if(strcmp(tmp, "n") == 0)
{
break;
}
}

point = (student_t *)malloc(sizeof(student_t));
printf("\n====请输入第%d个学生信息====\n", count);
printf("学号:");
gets(point->num);
q = head;
while(NULL != q)
{
if(atoi(q->num) == atoi(point->num))
{
flag = 1;
printf("学号输入重复或者不合格,请重新输入...\n");
break;
}
q = q->next;
}
if(1 == flag)
{
continue;
}
printf("姓名:");
gets(point->name);
printf("性别,('1'->男, '0'->女):");
point->sex = getchar();
getchar();
printf("年龄:");
gets(tmp);
point->age = atoi(tmp);
printf("三门课程的成绩:\n");
point->sum = 0;
for(i = 0; i < STUDENT_SUBJECT; ++i)
{
printf("第%d个成绩:", i + 1);
gets(tmp);
point->score[i] = atoi(tmp);
point->sum += point->score[i];
}
printf("总成绩:%d\n", point->sum);
point->next = head; // 核心代码就这两句
head = point;
count++;
}
printf("信息录入完毕,按任意键继续……");
getch();
}

// 显示所有学生的信息:遍历链表打印输出的过程
void display_all(void)
{
student_t *point = head;

printf("学号\t姓名\t性别\t年龄\t三门课程的成绩\t\t总成绩\n");

while(NULL != point)
{
if(0 == point->age)
{
point = point->next;
continue;
}
printf("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n", point->num, point->name, point->sex == '1' ? "男" : "女", point->age, *(point->score), *(point->score + 1), *(point->score + 2), point->sum);
point = point->next;
}
printf("信息显示完毕,按任意键继续……");
getch();
}

// 通过学号查找:唯一性
void search_on_number(void)
{
student_t *point = head;
char tmp[STUDENT_NUMBER];
uint8_t flag = 0;
printf("请输入学号:");
gets(tmp);
printf("学号\t姓名\t性别\t年龄\t三门课程的成绩\t\t总成绩\n");

while(NULL != point)
{
if(strcmp(tmp, point->num) == 0)
{
flag = 1;
printf("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n", point->num, point->name, point->sex == '1' ? "男" : "女", point->age, *(point->score), *(point->score + 1), *(point->score + 2), point->sum);
}
point = point->next;
}
if(0 == flag)
{
printf("\n未找到学号是%s的学生,按任意键继续……", tmp);
}
else
{
printf("\n显示完毕,按任意键继续……");
}
getch();
}

// 通过名字查找:不唯一
void search_on_name(void)
{
student_t *point = head;
char tmp[STUDENT_NAME];
uint8_t flag = 0;

printf("请输入姓名:");
gets(tmp);
printf("学号\t姓名\t性别\t年龄\t三门课程的成绩\t\t总成绩\n");

while(NULL != point)
{
if(strstr(point->name, tmp))
{
flag = 1;
printf("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n", point->num, point->name, point->sex == '1' ? "男" : "女", point->age, *(point->score), *(point->score + 1), *(point->score + 2), point->sum);
}
point = point->next;
}

if(0 == flag)
{
printf("\n未找到学号是%s的学生,按任意键继续……", tmp);
}
else
{
printf("\n显示完毕,按任意键继续……");
}
getch();
}

// 通过年龄查找:不唯一
void search_on_age(void)
{
student_t *point = head;
char tmp[30];
uint8_t flag = 0;

printf("请输入年龄:");
gets(tmp);
printf("学号\t姓名\t性别\t年龄\t三门课程的成绩\t\t总成绩\n");

while(NULL != point)
{
if(atoi(tmp) == point->age)
{
flag = 1;
printf("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n", point->num, point->name, point->sex == '1' ? "男" : "女", point->age, *(point->score), *(point->score + 1), *(point->score + 2), point->sum);
}
point = point->next;
}

if(flag == 0)
{
printf("\n未找到年龄是%s的学生,按任意键继续……", tmp);
}
else
{
printf("\n显示完毕,按任意键继续……");
}
getch();
}

// 修改指定学号的学生信息
void modify(void)
{
student_t *point = head;
char tmp[STUDENT_NUMBER];
uint8_t flag = 0, j;
char a;

printf("请输入学号:"); // 学号是唯一的
gets(tmp);

while(point != NULL)
{
if(strcmp(tmp, point->num) == 0)
{
flag = 1;
printf("学号\t姓名\t性别\t年龄\t三门课程的成绩\t\t总成绩\n");
printf("%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n", point->num, point->name, point->sex == '1' ? "男" : "女", point->age, *(point->score), *(point->score + 1), *(point->score + 2), point->sum);
printf("\n====请输入新信息====\n");
// 学号唯一不做修改,别的都可以修改
printf("姓名:");
gets(tmp);
if(strcmp(tmp, "") != 0)
{
strcpy(point->name, tmp);
}
printf("性别,'1'->男, '0'->女:");
a = getchar();
if('\n' != a)
{
point->sex = a;
}
else
{
point->sex = '1'; // 默认男生
}
printf("年龄:");
gets(tmp);
if(strcmp(tmp, "") != 0)
{
point->age = atoi(tmp);
}
else
{
point->age = 20; // 默认就20岁了
}
printf("三门课程的成绩:\n");
point->sum = 0;
for(j = 0; j < STUDENT_SUBJECT; ++j)
{
printf("第%d科成绩:", j + 1);
gets(tmp);
if(strcmp(tmp, "") != 0)
{
point->score[j] = atoi(tmp);
}
point->sum += point->score[j];
}
printf("总成绩:%d\n", point->sum);
}
point = point->next;
}
if(0 == flag)
{
printf("\n未找到%s!按任意键继续……", tmp);
}
else
{
printf("\n修改完毕,按任意键继续……");
}
getch();
}

// 删除指定学生的信息:删除某个链表结点
void delete(void)
{
student_t *point = head, *back;
char tmp[STUDENT_NUMBER];
uint8_t flag = 0, j;
char a;

printf("请输入学号:"); // 学号是唯一的
gets(tmp);

while(1)
{
if(NULL == point->next)
{
break;
}
if(atoi(tmp) == atoi(point->num))
{
flag = 1;
head = point->next;
free(point);
count--;
break;
}
back = point;
point = point->next;
if(atoi(tmp) == atoi(point->num))
{
flag = 1;
back->next = point->next;
free(point);
count--;
break;
}
}

if(0 == flag)
{
printf("\n未找到%s!按任意键继续……", tmp);
}
else
{
printf("\n修改完毕,按任意键继续……");
}
getch();
}

// 保存到指定路径
void save(void)
{
FILE *fp;
student_t *point = head;
char filename[FILENAME_SIZE] = {"d://qq.dat"};
printf("请输入文件名如%s:", filename);
gets(filename);

while(strcmp(filename , "") == 0)
{
printf("文件名不能为空,请重新输入:");
gets(filename);
}
if((fp = fopen(filename, "wb")) == NULL)
{
printf("文件打开失败!\n按任意键继续……");
getch();
return;
}
printf("正在保存信息,请耐心等待……\n");
count = 0;
while(NULL != point)
{
count++;
fwrite(point, sizeof(student_t), 1, fp);
point = point->next;
}
fclose(fp);
printf("信息保存成功,按任意键继续……");
getch();
}

// 从指定文件读取学生的信息到链表
void load(void)
{
FILE *fp;
student_t *point, *q;
char filename[FILENAME_SIZE] = {"d://qq.dat"};
printf("请输入文件名如%s:", filename);
gets(filename);

while(strcmp(filename , "") == 0)
{
printf("文件名不能为空,请重新输入:");
gets(filename);
}
if((fp = fopen(filename, "rb")) == NULL)
{
printf("文件打开失败!\n按任意键继续……");
getch();
return;
}

printf("正在从文件载入信息,请耐心等待……\n");
point = (student_t *)malloc(sizeof(student_t));
head = point;
count = 0;

while(!feof(fp))
{
count++;
fread(point, sizeof(struct student), 1, fp);
point->next = (student_t *)malloc(sizeof(student_t));
q = point;
point = point->next;
}
q->next = NULL;
fclose(fp);
printf("学生信息载入成功,按任意键继续……");
getch();
}

// 退出系统
void quit(void)
{
char c;
printf("你真的要退出系统吗?(Y/N)");

c = getchar();
if('Y' == c || 'y' == c)
{
printf("系统退出成功...\n");
exit(0);
}
}

int main(void)
{
uint8_t value;
char choice[3];

while(1)
{
system("cls");
menu();
do
{
printf("请输入功能键:");
gets(choice);
value = atoi(choice);
}
while((value > 12) || (value < 0));
switch(value)
{
case 1:
create();
break;
case 2:
display_all();
break;
case 3:
search_on_number();
break;
case 4:
search_on_name();
break;
case 5:
search_on_age();
break;
case 6:
modify();
break;
case 7:
delete();
break;
case 8:
save();
break;
case 9:
load();
break;
case 10:
quit();
break;
default:
break;
}
}

return 0;
}