page contents

C语言小项目——学生管理系统

/*  C语言小项目——学生管理系统 学习目标: 1. C语言知识点汇总与梳理 2. 编程思路的锻炼 功能分析: 需要实现哪些功能 录入学生的功能 按照....去查询 对信息修正  对信息进...

/*  C语言小项目——学生管理系统


学习目标:

1. C语言知识点汇总与梳理

2. 编程思路的锻炼



功能分析:

需要实现哪些功能


录入学生的功能

按照....去查询

对信息修正 

对信息进行删除 

排序 按照成绩倒序输出


导入和导出   文件操作

排序



登录--->登录界面


数据如何管理?


学生管理系统  --->多个学生的信息


顺序表  尾端能够快速插入(中间插入和删除不方便) 

连续存储 连续内存(申请不便)

链表 在任意地方插入删除都很简单 

查找不便(从头到尾查找)

栈 和队列



链表--->单链表  双链表 

  带一个头  函数比较好写



结构体  指针   文件操作  函数  传参 数组 循环

*/

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<Windows.h>

typedef struct student

{

char name[20];

int age;

float grade;

int ID;

//.....

struct student* pre;

struct student* next;

}STU;


void load()

{

char admin[20];

char passWord[20];

while (1)

{

printf("请输入你的账户\n");

gets(admin);

printf("请输入你的账户\n");

gets(passWord);

if (strcmp(admin, "summer") == 0 && strcmp(passWord, "123") == 0)

{

printf("账户和密码正确\n");

break;//输入正确  退出循环

}

else

{

printf("账户和密码不正确,请重新输入\n");

}

}

/*

如果有涉及到多个账号   选择文件保存

每次从文件中读取数据进行验证  验证 成功--->退出循环

*/

}

#if 0//二进制操作

void saveFile(STU*head)//保存所有的学生信息

{

FILE *fp = fopen("student.txt", "wb");//准备文件

//二进制方式  fwrite

//文本文件的方式 fprintf

STU*p = head->next;

while (p!= head)

{

//读取里面的数据

fwrite(p, sizeof(STU), 1, fp);//写入数据

p = p->next;

}

fclose(fp);

printf("写入成功\n");

}

void readFile(STU*head)

{

STU* p;

FILE* fp = fopen("student.txt", "rb");

if (fp == NULL) return;

while (1)

{

p= (STU*)malloc(sizeof(STU));//先准备一个结构体 

fread(p, sizeof(STU), 1, fp);//读取内容

if (feof(fp))

{

//已经读取完毕  不需要插入

free(p);//直接释放节点

break;//直接结束读取

}

//插入到链表当中(头插)

p->next = head->next;

p->pre = head;

p->pre->next = p;

p->next->pre = p;

//准备下一次读取

}

fclose(fp);

}

#else//文本文件的操作

void saveFile(STU*head)//保存所有的学生信息

{

FILE *fp = fopen("student.txt", "w");//准备文件

//二进制方式  fwrite

//文本文件的方式 fprintf

STU*p = head->next;

while (p != head)

{

//读取里面的数据

//fwrite(p, sizeof(STU), 1, fp);//写入数据

fprintf(fp, "%s\t%d\t%.1f\t%d\n", p->name, p->age, p->grade, p->ID);

p = p->next;

}

fclose(fp);

printf("写入成功\n");

}


void readFile(STU*head)

{

STU* p;

FILE* fp = fopen("student.txt", "r");

if (fp == NULL) return;


while (1)

{


p = (STU*)malloc(sizeof(STU));//先准备一个结构体 

//fread(p, sizeof(STU), 1, fp);//读取内容

//%s读取字符串 用空格或者\t或者换行隔开都可以

//不适合读取有空格的字符串

if(fscanf(fp, "%s\t%d\t%f\t%d\n", p->name, &p->age, &p->grade, &p->ID)==EOF)

{

//已经读取完毕  不需要插入

free(p);//直接释放节点

break;//直接结束读取

}

//插入到链表当中(头插)

p->next = head->next;

p->pre = head;

p->pre->next = p;

p->next->pre = p;

//准备下一次读取

}

fclose(fp);

}

#endif

void freeNode(STU*head)//删除整个链表

{

STU *p, *q;

p = head->next;

while (p != head)

{

q = p;

p = p->next;

free(q);

}

free(head);

}

void insertStu(STU*head)

{

STU*p = (STU*)malloc(sizeof(STU));

printf("请输入你要录入的名字\n");

scanf("%s", p->name);

printf("请输入你要录入的年龄\n");

scanf("%d", &p->age);

printf("请输入你要录入的成绩\n");

scanf("%f", &p->grade);

printf("请输入你要录入的学号\n");

scanf("%d", &p->ID);

//scanf_s("%s", p->name, 20);

//插入链表当中 (尾插)


p->next = head;

p->pre = head->pre;

p->pre->next = p;

p->next->pre = p;


}

void searchByName(STU *head)

{

char name[20];

printf("请输入你要查找的名字\n");

//strcmp  张三丰     输入 张三

//strstr 判断是否是子字符串

scanf("%s", name);

STU *p = head->next;

while (p != head)

{

//if (strcmp(p->name, name) == 0)

if (strstr(p->name,name))//没找到返回NULL

{

printf("名字:%s\t 年龄%d\t 分数%.1f\t学号%d\n", p->name, p->age, p->grade, p->ID);

}

p = p->next;

}

}


void changeStu(STU*head)//按照分数  修改信息

{

//先找出所有可能的选项  然后列举出来

//如果保存多个节点的首地址?  顺序表的方式来保存

STU* arr[100];//指针数组  用来存放节点的首地址

int len = 0;//存放的数据个数

float a, b,c;

int num;

printf("请输入你要查找的分数的范围 {a,b}");

scanf("%f %f", &a, &b);

if (a > b)//让a<b

{

c = a;

a = b;

b = c;

}

STU*p = head->next;

while (p != head)

{

if (p->grade >= a&&p->grade <= b)//找到一个学生

{

if (len >= 100)

{

//先不进行插入   一页满了

//先让用户看一下 有没有要修改的内容 有--->修改

//没有  这个表格清空

for (int i = 0; i < len; ++i)

{

printf("编号%d 名字:%s\t 年龄%d\t 分数%.1f\t学号%d\n",i+1,arr[i]->name, arr[i]->age, arr[i]->grade, arr[i]->ID);

}

printf("请选择你要修改的学生的编号");

scanf("%d", &num);

if (num <= len&&num>0)

{

printf("请输入你要录入的名字\n");

scanf("%s", arr[num-1]->name);

printf("请输入你要录入的年龄\n");

scanf("%d", &arr[num-1]->age);

printf("请输入你要录入的成绩\n");

scanf("%f", &arr[num-1]->grade);

printf("请输入你要录入的学号\n");

scanf("%d", &arr[num-1]->ID);

}

len = 0;//清空这个表

}

else

{

arr[len++] = p;//结点的位置插入到顺序表当中

}

}

p = p->next;

}

if (len!=0)

{

//先不进行插入   一页满了

//先让用户看一下 有没有要修改的内容 有--->修改

//没有  这个表格清空

for (int i = 0; i < len; ++i)

{

printf("编号%d 名字:%s\t 年龄%d\t 分数%.1f\t学号%d\n", i + 1, arr[i]->name, arr[i]->age, arr[i]->grade, arr[i]->ID);

}

printf("请选择你要修改的学生的编号");

scanf("%d", &num);

if (num <= len&&num>0)

{

printf("请输入你要录入的名字\n");

scanf("%s", arr[num - 1]->name);

printf("请输入你要录入的年龄\n");

scanf("%d", &arr[num - 1]->age);

printf("请输入你要录入的成绩\n");

scanf("%f", &arr[num - 1]->grade);

printf("请输入你要录入的学号\n");

scanf("%d", &arr[num - 1]->ID);

}

len = 0;//清空这个表

}

}


void deletStu(STU*head)

{

//按照什么方式去删除一个信息

//按照  学号 满足这个范围之内的  删除

int  x, y,z;

printf("请输入你要删除的ID的范围");

scanf("%d %d", &x, &y);

if (x > y)

{

z = x;

x = y;

y = z;

}


STU*p = head->next,*q;

while (p != head)

{


if (p->ID >= x&&p->ID <= y)

{

//找到了直接删除 

q = p;//q保留要删除的结点

p = p->next;

q->next->pre = q->pre;

q->pre->next = q->next;

free(q);

}

else

{

p = p->next;

}

}

}

void printAll(STU*head)

{

STU*p = head->next;

printf("学生的信息:\n");

while (p != head)

{

printf("名字:%s\t 年龄%d\t 分数%.1f\t学号%d\n", p->name, p->age, p->grade, p->ID);

p = p->next;

}

printf("-----------------------------------");

Sleep(2000);

}

void swap(STU*a, STU*b)//用结构体指针交换两个结构体

{

STU temp;//中间变量

//数据域和指针域

//指针域不动

temp = *a;

a->age = b->age;

a->ID = b->ID;

a->grade = b->grade;

strcpy(a->name, b->name);


b->age = temp.age;

b->ID =temp.ID;

b->grade = temp.grade;

strcpy(b->name, temp.name);


}

void sort(STU *head)

{

//按照学号排序  选择 交换

STU*p, *q,*temp;

for (p = head->next; p != head; p = p->next)//从头到尾

{

//找到最小的学号

temp = p;

for (q = p->next; q != head; q = q->next)

{

if (temp->ID > q->ID)

{

temp = q;//每次保留更小的结点位置

}

}

swap(temp, p);//交换两个位置的结点

}

}

void menu()//菜单

{

int choice;//用户的选择

STU* head = (STU*)malloc(sizeof(STU));

head->next = head->pre = head;//初始化操作

//循环双链表  作为存放数据的链表

readFile(head);//进入菜单之前 读取文件内容


while (1)//循环

{

system("cls");//清屏函数

printf("欢迎进入学生管理系统\n");

printf("请输入你要使用的功能\n");

printf("1.录入信息\n");

printf("2.查询信息\n");

printf("3.修改信息\n");

printf("4.删除信息\n");

printf("5.打印信息\n");

printf("6.排序\n");

printf("0.退出菜单\n");

scanf("%d", &choice);

switch (choice)

{

case 0://退出

saveFile(head);//对于信息 是否需要保存?

freeNode(head);//释放内存

return;//退出这个函数  堆内存需要释放

break;

case 1://录入

insertStu(head);//录入学生信息

break;

case 2://查询

while (choice)

{

system("cls");//清屏函数

printf("开始查询  选择你要的查询方式\n");

printf("1.按照名字查询\n");

//....

printf("0.退出\n");

scanf("%d", &choice);

switch (choice)

{

case 1:

searchByName(head);

break;

case 0://退出

break;

default:

break;

}

}

break;

case 3://修改

changeStu(head);

break;

case 4://删除

deletStu(head);

break;

case 5://全部打印

printAll(head);

break;

case 6://排序

//根据年龄?成绩?名字?学号?

//strcmp >0

//英文字典

//abc < bac

sort(head);

break;

default:

break;

}

}

}

int main()

{

menu();    //主菜单

getchar();

return 0;

}

  • 发表于 2021-05-12 14:10
  • 阅读 ( 654 )
  • 分类:C/C++开发

0 条评论

请先 登录 后评论
小威
小威

64 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章