学生信息管理系统,C语言链表实现
这是我自学编程的第一个想法及项目,想着别人都是数组做,我自己用链表实现,对于刚学的我真的很困难,但是咬着牙花了两天写完了,算是对自己努力的一个记录
读取和保存函数是实现功能的重要函数,在每次修改前需要调用读取函数拉起链表,修改后需要调用保存函数,存入文件
0.0读取学生信息
void ReadStudent(){
FILE * fp;
char k;
if ((fp = fopen("D:\\demo.txt", "r")) == NULL) { //以只读方式打开文件
printf("无学生信息");
exit(1);
}
//从文件读取信息
while (!feof(fp)){
Node* p = (Node*)malloc(sizeof(Node)); //初始化一个结点p
fscanf(fp,"%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, &p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p->next = Head->next; //头插p结点
Head->next = p;
}
}
0.1保存学生信息
void SaveStudent() {
FILE *fp;
fp=fopen("D:\\demo.txt","w"); //以只写方式打开文件
if( fp== NULL ){
printf("打开文件失败\n");
exit(1); //退出程序
}
Node* p = Head->next;
while (p != NULL) { //依次写入文件
fprintf(fp, "%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p = p->next;
}
fclose(fp);
}
下面实现增加、查找、修改、删除功能
1.录入学生信息
void InputStudent() {
int x;
printf("您想要录入的学生人数:");
scanf("%d", &x);
int j = 1;
while (x) {
Node* p = (Node*)malloc(sizeof(Node));
printf("录入第%d个学生信息\n", j++);
printf("请输入学生的学号:");
scanf("%s", p->stu.stuNum);
Node* k = Head->next;
while (k != NULL) {
while (strcmp(p->stu.stuNum,k->stu.stuNum)==0) {
printf("该学号已存在,请重新输入!\n");
printf("请输入学生的学号:");
scanf("%s", p->stu.stuNum);
}
k = k->next;
}
printf("请输入学生的姓名:");
scanf("%s", p->stu.stuName);
printf("请输入学生的性别:");
scanf("%s", p->stu.stuSex);
printf("请输入学生的年龄:");
scanf("%d", &p->stu.stuAge);
printf("请输入学生的班级:");
scanf("%s", p->stu.stuClass);
printf("请输入学生的成绩:");
scanf("%s", p->stu.stuScore);
p->next = Head->next;
Head->next = p;
x--;
}
}
2.查找学生信息
void SearchStudent(){
int n;
char s[20];
printf("请选择查找方式\n");
printf("1.根据学号查找\n");
printf("2.根据姓名查找\n");
scanf("%d",&n);
switch (n){
case 1:{
ReadStudent();//从文件将链表读入,Head为头结点
int flag=0;
Node* p=Head->next;
printf("请输入想查找的学号:");
scanf("%s",s);
while(p!=NULL){
if(strcmp(p->stu.stuNum,s)==0){ //字符串匹配
printf("学号\t姓名\t性别\t年龄\t班级\t成绩\n");
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有符合条件的学生\n");
}
}
break;
case 2: {
ReadStudent();
int flag=0;
Node* p=Head->next;
printf("请输入想查找的姓名:");
scanf("%s",s);
while(p){
if(strcmp(p->stu.stuName,s)==0){
printf("学号\t姓名\t性别\t年龄\t班级\t成绩\n");
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有符合条件的学生");
}
}
break;
}
}
3.修改学生信息
void ModifyStudent(){
printf("请输入你想修改学生的姓名\n");
char s[20];
char num[20];
char name[20];
char sex[20];
int age;
char classs[20];
char score[20];
Head->next=NULL;//重要,如果要保存链表,每次读取链表前都要将头指针指向空,不然数据会重复
ReadStudent();//读入链表
int flag=0;
Node* p=Head->next;
scanf("%s",s);
while(p!=NULL){
if(strcmp(p->stu.stuName,s)==0){
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有找到该学生");
}else{
printf("请输入想修改的内容:\n");
printf("1.学生学号\n");
printf("2.学生姓名\n");
printf("3.学生性别\n");
printf("4.学生年龄\n");
printf("5.学生班级\n");
printf("6.学生成绩\n");
int n;
scanf("%d",&n);
switch(n){
case 1:
printf("将学号修改为:");
scanf("%s",num);
strrpl(p->stu.stuNum,num); //strrpl为字符串替换函数,见末尾
break;
case 2:
printf("将姓名修改为:");
scanf("%s",name);
strrpl(p->stu.stuName,name);
break;
case 3:
printf("将性别修改为:");
scanf("%s",sex);
strrpl(p->stu.stuSex,sex);
break;
case 4:
printf("将年龄修改为:");
scanf("%d",&age);
p->stu.stuAge=age;
break;
case 5:
printf("将班级修改为:");
scanf("%s",classs);
strrpl(p->stu.stuClass,classs);
break;
case 6:
printf("将成绩修改为:");
scanf("%s",score);
strrpl(p->stu.stuScore,score);
break;
}
}
}
修改的时候需要用到字符替换函数
//字符替换 s1替换为s2
void strrpl(char q1[20],char q2[20]){
int i=0,j=0;
while(q1[i]!='\0'){
q1[i++]='\0';
}
i=0;
while(q2[j]!='\0'){
q1[i++]=q2[j++];
}
}
4.删除学生信息
void DeleStudent(){
Head->next=NULL;//重要,如果要保存链表,每次读取链表前都要将头指针指向空,不然数据会重复
ReadStudent();
char name[20];
Node*p=Head->next;
Node*q=Head;
printf("要删除学生姓名\n");
scanf("%s",name);
while(p!=NULL){
if(strcmp(p->stu.stuName,name)==0){
q->next=p->next;
free(p);
}
q=q->next;
p=p->next;
}
}
最后实现统计和查看功能
5.统计学生人数
void NumStudent(){
FILE* fp;
char w;
int num=0;
if ((fp = fopen("D:\\demo.txt", "r")) == NULL) {
printf("无学生信息");
}else{
fp = fopen("D:\\demo.txt", "r");
while ((w=fgetc(fp))!=EOF){
if(w=='\n'){ //根据换行数统计学生人数
num++;
}
}
printf("共有学生%d人\n",num);
}
}
6.查看录入学生信息
void PrintStudent() {
Head->next=NULL;
ReadStudent();
Node* p=Head->next;
while (p){
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p=p->next;
}
}
全部代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
typedef struct _Student { //学生结点数据域结构体
char stuNum[20]; //学号
char stuName[20]; //姓名
char stuSex[20]; //性别
int stuAge; //年龄
char stuClass[20]; //班级
char stuScore[20]; //分数
}Student;
typedef struct _Node { //学生结点
Student stu; //学生
struct _Node* next;//指针域
}Node;
void Welcome();//欢迎界面
void ReadStudent();//读取学生信息
void SaveStudent();//保存学生信息
void InputStudent();//录入学生信息
void NumStudent();//统计学生人数
void SearchStudent();//查找学生信息
void ModifyStudent();//修改学生信息
void DeleStudent();//删除学生信息
void PrintStudent();//查看录入信息
void Help();//使用帮助
void strrpl(char s1[20],char s2[20]);//字符替换
Node* Head;//全局头结点
int main() {
system("color 3a");//改变控制台颜色
Head = (Node*)malloc(sizeof(Node));
Head->next = NULL;//初始化一个头结点
Welcome(); //欢迎界面
int n;
while (1) {
printf("请选择想使用的功能\n");
scanf("%d", &n);//输入一个数字
switch (n) {
case 1: InputStudent(); //1.录入学生信息
SaveStudent();
break;
case 2: NumStudent(); //2.统计学生信息
break;
case 3: SearchStudent(); //3.查找学生信息
break;
case 4: ModifyStudent(); //4.修改学生信息
SaveStudent();
break;
case 5: DeleStudent(); //5.删除学生信息
SaveStudent();
break;
case 6: PrintStudent(); //6.查看录入信息
break;
case 7: Help(); //7.使用帮助
break;
case 0: exit(0);
}
}
return 0;
}
//欢迎界面
void Welcome() {
printf("===============================================\n");
printf("===========欢迎使用学生管理系统 v1.0===========\n");
printf("= =\n");
printf("= 1.录入学生信息 =\n");
printf("= 2.统计学生人数 =\n");
printf("= 3.查找学生信息 =\n");
printf("= 4.修改学生信息 =\n");
printf("= 5.删除学生信息 =\n");
printf("= 6.查看录入信息 =\n");
printf("= 7.查看使用帮助 =\n");
printf("= 0.退出系统 =\n");
printf("= =\n");
printf("===============================================\n");
}
//读取学生信息
void ReadStudent(){
FILE * fp;
char k;
if ((fp = fopen("D:\\demo.txt", "r")) == NULL) { //以只读方式打开文件
printf("无学生信息");
exit(1);
}
//从文件读取信息
while (!feof(fp)){
Node* p = (Node*)malloc(sizeof(Node)); //初始化一个结点p
fscanf(fp,"%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, &p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p->next = Head->next; //头插p结点
Head->next = p;
}
}
//保存学生信息
void SaveStudent() {
FILE *fp;
fp=fopen("D:\\demo.txt","w"); //以只写方式打开文件
if( fp== NULL ){
printf("打开文件失败\n");
exit(1); //退出程序
}
Node* p = Head->next;
while (p != NULL) { //依次写入文件
fprintf(fp, "%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p = p->next;
}
fclose(fp);
}
//1.录入学生信息
void InputStudent() {
int x;
printf("您想要录入的学生人数:");
scanf("%d", &x);
int j = 1;
while (x) {
Node* p = (Node*)malloc(sizeof(Node));
printf("录入第%d个学生信息\n", j++);
printf("请输入学生的学号:");
scanf("%s", p->stu.stuNum);
Node* k = Head->next;
while (k != NULL) {
while (strcmp(p->stu.stuNum,k->stu.stuNum)==0) {
printf("该学号已存在,请重新输入!\n");
printf("请输入学生的学号:");
scanf("%s", p->stu.stuNum);
}
k = k->next;
}
printf("请输入学生的姓名:");
scanf("%s", p->stu.stuName);
printf("请输入学生的性别:");
scanf("%s", p->stu.stuSex);
printf("请输入学生的年龄:");
scanf("%d", &p->stu.stuAge);
printf("请输入学生的班级:");
scanf("%s", p->stu.stuClass);
printf("请输入学生的成绩:");
scanf("%s", p->stu.stuScore);
p->next = Head->next;
Head->next = p;
x--;
}
}
//2.统计学生人数
void NumStudent(){
FILE* fp;
char w;
int num=0;
if ((fp = fopen("D:\\demo.txt", "r")) == NULL) {
printf("无学生信息");
}else{
fp = fopen("D:\\demo.txt", "r");
while ((w=fgetc(fp))!=EOF){
if(w=='\n'){ //根据换行数统计学生人数
num++;
}
}
printf("共有学生%d人\n",num);
}
}
//3.查找学生信息
void SearchStudent(){
int n;
char s[20];
printf("请选择查找方式\n");
printf("1.根据学号查找\n");
printf("2.根据姓名查找\n");
scanf("%d",&n);
switch (n){
case 1:{
ReadStudent();//从文件将链表读入,Head为头结点
int flag=0;
Node* p=Head->next;
printf("请输入想查找的学号:");
scanf("%s",s);
while(p!=NULL){
if(strcmp(p->stu.stuNum,s)==0){ //字符串匹配
printf("学号\t姓名\t性别\t年龄\t班级\t成绩\n");
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有符合条件的学生\n");
}
}
break;
case 2: {
ReadStudent();
int flag=0;
Node* p=Head->next;
printf("请输入想查找的姓名:");
scanf("%s",s);
while(p){
if(strcmp(p->stu.stuName,s)==0){
printf("学号\t姓名\t性别\t年龄\t班级\t成绩\n");
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有符合条件的学生");
}
}
break;
}
}
//4.修改学生信息
void ModifyStudent(){
printf("请输入你想修改学生的姓名\n");
char s[20];
char num[20];
char name[20];
char sex[20];
int age;
char classs[20];
char score[20];
Head->next=NULL;//重要,如果要保存链表,每次读取链表前都要将头指针指向空,不然数据会重复
ReadStudent();//读入链表
int flag=0;
Node* p=Head->next;
scanf("%s",s);
while(p!=NULL){
if(strcmp(p->stu.stuName,s)==0){
flag=1;
break;
}
p=p->next;
}
if(flag==0){
printf("没有找到该学生");
}else{
printf("请输入想修改的内容:\n");
printf("1.学生学号\n");
printf("2.学生姓名\n");
printf("3.学生性别\n");
printf("4.学生年龄\n");
printf("5.学生班级\n");
printf("6.学生成绩\n");
int n;
scanf("%d",&n);
switch(n){
case 1:
printf("将学号修改为:");
scanf("%s",num);
strrpl(p->stu.stuNum,num); //strrpl为字符串替换函数,见末尾
break;
case 2:
printf("将姓名修改为:");
scanf("%s",name);
strrpl(p->stu.stuName,name);
break;
case 3:
printf("将性别修改为:");
scanf("%s",sex);
strrpl(p->stu.stuSex,sex);
break;
case 4:
printf("将年龄修改为:");
scanf("%d",&age);
p->stu.stuAge=age;
break;
case 5:
printf("将班级修改为:");
scanf("%s",classs);
strrpl(p->stu.stuClass,classs);
break;
case 6:
printf("将成绩修改为:");
scanf("%s",score);
strrpl(p->stu.stuScore,score);
break;
}
}
}
//5.删除学生信息
void DeleStudent(){
Head->next=NULL;//重要,如果要保存链表,每次读取链表前都要将头指针指向空,不然数据会重复
ReadStudent();
char name[20];
Node*p=Head->next;
Node*q=Head;
printf("要删除学生姓名\n");
scanf("%s",name);
while(p!=NULL){
if(strcmp(p->stu.stuName,name)==0){
q->next=p->next;
free(p);
}
q=q->next;
p=p->next;
}
}
//6.查看录入信息
void PrintStudent() {
Head->next=NULL;
ReadStudent();
Node* p=Head->next;
while (p){
printf("%s\t%s\t%s\t%d\t%s\t%s\n", p->stu.stuNum, p->stu.stuName, p->stu.stuSex, p->stu.stuAge, p->stu.stuClass, p->stu.stuScore);
p=p->next;
}
}
//7.使用帮助
void Help(){
printf("1.程序将自动在D盘根目录下新建一个demo.txt文件用来储存学生信息\n");
printf("2.根据提示在键盘上选择对应的数字完成交互\n");
}
//字符替换 s1替换为s2
void strrpl(char q1[20],char q2[20]){
int i=0,j=0;
while(q1[i]!='\0'){
q1[i++]='\0';
}
i=0;
while(q2[j]!='\0'){
q1[i++]=q2[j++];
}
}