学习目标:掌握用c语言写常见管理系统。
学习内容:
1.单链表的建立;
2.从链表中删除节点;
3.头插法建立动态链表;
4.构建结构体;
一,头文件部分.
/**
@Onely44
首先新建一个文件名为 StudentMange.h 的头文件
将头文件部分的所有内容写到该文件中
*/
#define _CRT_SECURE_NO_WARNINGS //若使用的编译器不是vs,预处理指令可省略
#include<stdio.h>
#include<conio.h> //包含_getch()函数,不用scanf()函数接收是为了避免程序卡顿
#include<stdlib.h> // 包含malloc()函数用于申请动态内存分配
#include<string.h> // 包含字符串一系列处理函数
typedef struct _student {
char name[25];
int stuNum; // 创建一个用于储存学生信息的结构体并利用typedef为新类型命名
int age;
int score;
}student;
typedef struct _node {
student stu; // 创建一个节点,为程序建立动态链表做准备
struct _node* next;
}node;
node* head = NULL; // 创建头指针
void Welcome(); // 声明系统部分用到的所有函数,使程序结构化
void Record();
void printStu();
void saveStu();
void readStu();
int recordStu();
node* searchStu();
void changeStu();
void deleStu();
二,系统部分
#include"StudentMange.h"
int main()
{
// 主函数是程序的入口
while (1) // 设置一个永真循环,将要实现的功能全写入循环内
{
Welcome();
char ch = _getch();
switch (ch) // switch()分支循环对用户输入做判断
{
case '1':
Record();
break; // break语句跳出循环
case '2':
printStu();
break;
case '3':
saveStu();
break;
case '4':
readStu();
break;
case '5':
printf("学生总人数为:%d\n", recordStu());
system("pause");
system("cls");
break;
case '6':
{node* t = searchStu();
if (t != NULL)
{
printf("学号 %d\t*\t姓名 %s\t*\t成绩 %d *\t年龄 %d\t*\n",
t->stu.stuNum,
t->stu.name,
t->stu.score,
t->stu.age);
}
else
printf("没有找到该学生;\n");
system("pause"); // 暂停
system("cls"); // 清屏,全程序内这两个函数功能一致
break;
}
case '7':
changeStu();
break;
case '8':
deleStu();
break;
case '9':
printf("Bye Bye!!\n");
system("pause");
return 0; // 使用return语句可直接结束程序
default:
printf("您的输入有误,请重新输入。\n");
system("pause");
system("cls");
break;
}
}
return 0;
}
void Welcome() // 打印欢迎界面
{
printf("*************************************************\n");
printf("*\t欢迎使用高校学生成绩管理系统v6.6\t*\n");
printf("*************************************************\n");
printf("*\t\t1.录入学生信息\t\t\t*\n");
printf("*\t\t2.打印学生信息\t\t\t*\n");
printf("*\t\t3.保存学生信息\t\t\t*\n");
printf("*\t\t4.读取学生信息\t\t\t*\n");
printf("*\t\t5.统计所有学生人数\t\t*\n");
printf("*\t\t6.查找学生信息\t\t\t*\n");
printf("*\t\t7.修改学生信息\t\t\t*\n");
printf("*\t\t8.删除学生信息\t\t\t*\n");
printf("*\t\t9.退出系统\t\t\t*\n");
printf("*************************************************\n");
}
void Record() // 录入学生信息
{
node* p = (node*)malloc(sizeof(node)); // 定义一个指向节点类型的指针,并使用动态内存分配开辟一块节点大小的空间
p->next = NULL; // 指针无指向时将其置空,良好编程习惯
if (head == NULL)
{
head = p; // 创建一个动态节点
}
else
{
p->next = head;
head = p;
}
printf("请输入学生姓名\n");
scanf("%s", p->stu.name);
printf("请输入学生学号\n");
scanf("%d", &p->stu.stuNum);
printf("请输入学生年龄\n");
scanf("%d", &p->stu.age);
printf("请输入学生成绩\n");
scanf("%d", &p->stu.score);
printf("学生信息录入成功.\n");
system("pause");
system("cls");
}
void printStu() // 打印学生信息
{
system("cls");
printf("*************************************************\n");
printf("*\t欢迎使用高校学生成绩管理系统v6.6\t*\n");
printf("*************************************************\n");
printf("* 学号\t*\t姓名\t*\t成绩 *\t年龄\t*\n");
printf("*************************************************\n");
node* p = head;
for (p; p != NULL; p = p->next)
{
printf("* %d\t*\t%s\t*\t%d *\t%d\t*\n",
p->stu.stuNum,
p->stu.name,
p->stu.score, // 遍历动态链表,获取到每一个学生的信息并输出
p->stu.age);
}
printf("*************************************************\n");
system("pause");
system("cls");
}
void saveStu() // 保存学生信息
{
FILE *fp=fopen("Stu.txt", "w"); // 定义一个文件指针
if (fp == NULL)
{
printf("打开文件失败.\n");
return;
}
node* p = head;
for (p; p != NULL; p = p->next)
{
fwrite(&p->stu, sizeof(student), 1, fp); // 将要保存的信息写入到指定文件中
}
fclose(fp); // 关闭文件
printf("信息保存成功!\n");
system("pause");
system("cls");
}
void readStu() // 读取学生信息
{
FILE* fp = fopen("Stu.txt", "r");
if (fp == NULL)
{
printf("\n打开文件失败\n");
return;
}
student stu;
while (fread(&stu, sizeof(student), 1, fp)) // 遍历链表,使用文件读操作,将学生信息从文件中输出
{
node* pnew = (node*)malloc(sizeof(node));
pnew->next = NULL;
memcpy(pnew, &stu, sizeof(student));
if (head == NULL)
{
head = pnew;
}
else
{
pnew->next = head;
head = pnew;
}
}
fclose(fp);
printf("加载数据成功!\n");
system("pause");
system("cls");
}
int recordStu()
{
int count = 0;
node* p = head;
while (p != NULL) // 统计学生人数,遍历链表循环计数,将值返回主函数
{
count++;
p = p->next;
}
return count;
}
node* searchStu() // 查找学生信息
{
char stuName[20];
int stuNum;
printf("请输入需要查找学生的学号:\n");
scanf("%d", &stuNum);
printf("请输入需要查找学生的姓名:\n");
scanf("%d", &stuName);
node* p = head;
while (p != NULL) // 遍历链表,使用判断语句找出需要查找的学生学号
{
if (p->stu.stuNum == stuNum || strcmp(stuName, p->stu.name) == 0)
{
return p;
}
p = p->next;
}
return NULL;
}
void changeStu() // 修改学生信息
{
int stuNum;
printf("请输入要修改学生的学号:\n");
scanf("%d", &stuNum);
node* p = head;
while (p != NULL) // 同样是先遍历后类似查找操作,找到对应学生进行修改
{
if (p->stu.stuNum == stuNum)
{
printf("学号 %d\t*\t姓名 %s\t*\t成绩 %d *\t年龄 %d\t*\n",
p->stu.stuNum,
p->stu.name, // 这种对结构体内存储数据的打印类似于‘剥洋葱’
p->stu.score,
p->stu.age);
printf("请输入改动后的姓名:\n");
scanf("%s", p->stu.name);
printf("请输入改动后的成绩:\n");
scanf("%d", &p->stu.score);
printf("请输入改动后的年龄:\n");
scanf("%d", &p->stu.age);
printf("修改数据成功!");
break;
}
p = p->next;
}
if (p == NULL)
{
printf("没有找到该学生的信息\n");
}
system("pause");
system("cls");
}
void deleStu() // 删除学生信息
{
int nstuNum;
printf("请输入要删除学生的学号:\n");
scanf("%d", &nstuNum);
node* p;
if (head->stu.stuNum == nstuNum) // 1,要删除的学生位于头结点
{
p = head;
head = head->next;
free(p);
printf("已删除该学生信息.\n");
system("pause");
system("cls");
return;
}
node* p1 = head;
node* p2;
while (p1->next != NULL) // 2, 要删除的学生位于中间节点
{
if (p1->next->stu.stuNum == nstuNum)
{
p2 = p1->next;
p1->next = p1->next->next;
free(p2);
printf("已删除该学生信息.\n");
system("pause");
system("cls");
return;
}
p1 = p1->next;
if (p1->next == NULL)
{
break;
}
}
if (p1->next == NULL)
{
printf("没有找到该学生的信息\n"); // 该学生信息不存在
}
system("pause");
system("cls");
}