学生管理系统,添加文件相关操作,实现把数据保存在文件中。
FILE *fp = fopen("student.txt", "r"); //打开文件,打开失败,返回NULL
if(fp == NULL)
{
FILE *fp = fopen("student.txt", "w+"); //打开文件失败,在当前目录下创建并读写打开
}
else
{
Load(head); //如果已经有文件,进行加载学生信息函数
}
文件操作主要是在原本指针版的代码中添加两个函数,一是保存学生信息到文件中,二是加载学生信息。
一、保存学生信息
void Save(struct Node *head)
{
FILE *fp = fopen("student.txt", "w+");
fprintf(fp,"共有%d个学生信息\n",count);
fprintf(fp,"学号\t姓名\t性别\t年龄\t成绩\n");
struct Node *temp = head->next;
while(temp != NULL)
{
fprintf(fp,"%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
temp = temp->next;
}
fclose(fp);
}
二、加载学生信息。就是把文件中保存的学生信息链接到创建的链表中。
void Load(struct Node *head)
{
struct Node *end = head;
FILE *fp = fopen("student.txt", "a+");
if(fgetc(fp)==EOF)
{
printf("文件为空\n");
return;
}
else
{
fseek(fp,-1,1); //光标往前偏移一位
fscanf(fp,"共有%d个学生信息\n",&count);
fscanf(fp,"学号\t姓名\t性别\t年龄\t成绩\n");
while(fgetc(fp)!=EOF)
{
fseek(fp,-1,1); //光标往前偏移一位
struct Node *new3 = (struct Node *)malloc(sizeof(struct Node));
fscanf(fp,"%d\t%s\t%s\t%d\t%f\n",&new3->student.id,new3->student.name,new3->student.sex,&new3->student.age,&new3->student.score);
new3->next = NULL;
end->next = new3;
end = new3;
}
fclose(fp);
}
}
完整代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//学生信息结构体
struct Stu{
char name[20];
int id;
int age;
char sex[2]; //性别
float score;
};//数据域
//节点结构体
struct Node{
struct Stu student; //数据
struct Node *next; //指针指向下一空间
}; // 指针域
enum Tag{quit,add,del,change,find,rank,print,charu};
int count;
void menu(); //菜单
void Add(struct Node *head); //1.添加学生信息
void Del(struct Node *head); //2.删除学生信息
void Change(struct Node *head); //3.修改学生信息
void Find(struct Node *head); //4.查看单个学生信息
void Rank(struct Node *head); //5.学生信息排序
void Print(struct Node *head); //6.遍历学生信息
void Charu(struct Node *head); //7.插入学生信息
void Save(struct Node *head); //保存学生信息
void Load(struct Node *head); //加载学生信息
int main()
{
int i=0,f=0;
char mima[20]={"666666"}; //密码可以直接设定,也可以手动输入设置密码
char password[20] = {0};
for (i = 0; i < 3; i++)
{
f++;
printf("请输入密码:");
scanf("%s",password);
if (0 == strcmp(password,mima))
{
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
memset(head,0,sizeof(struct Stu));
head->next = NULL;
FILE *fp = fopen("student.txt", "r");
if(fp == NULL)
{
FILE *fp = fopen("student.txt", "w+");
}
else
{
Load(head);
}
while(1)
{
int num;
menu();
printf("请输入要执行的操作!\n");
scanf("%d",&num);
switch(num)
{
case add:
Add(head);
break;
case del:
Del(head);
break;
case change:
Change(head);
break;
case find:
Find(head);
break;
case rank:
Rank(head);
break;
case print:
Print(head);
break;
case charu:
Charu(head);
break;
case quit:
Save(head);
return 0;
default:printf("输入有误,请重新输入!\n");
}
}
}
else
{
printf("密码输入错误,您还有%d次输入机会!\n",3-f);
}
}
if (i < 3)
{
printf("登录成功\n");
}
else
{
printf("退出程序\n");
}
return 0;
}
//学生管理系统菜单
void menu()
{
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");
}
//1.添加学生信息
void Add(struct Node *head)
{
int n,m;
loop:
printf("请输入要添加的学号!\n");
scanf("%d",&n);
struct Node *temp = head->next;
while(temp != NULL)
{
if(n == temp->student.id)
{
printf("该学号已存在!\n");
return;//无返回值
}
temp = temp->next ;
}
struct Node *new1 = (struct Node *)malloc(sizeof(struct Node));
new1->student.id = n;
printf("请输入要添加的学生姓名!\n");
scanf("%s",new1->student.name);
printf("请输入要添加的学生性别!\n");
scanf("%s",new1->student.sex);
printf("请输入要添加的学生的年龄!\n");
scanf("%d",&new1->student.age);
printf("请输入要添加的学生成绩!\n");
scanf("%f",&new1->student.score);
new1->next =NULL;
temp = head;
while(temp->next != NULL)
{
temp = temp->next ;
}
temp->next = new1;
count++;
printf("该学生信息添加成功!\n");
printf("是否要继续添加? 是......1,否......2\n");
scanf("%d",&m);
if(m == 1)
{
goto loop;
}
else if(m == 2)
{
return;
}
}
//2.删除学生信息
void Del(struct Node *head)
{
struct Node *temp1 = head;
struct Node *temp2 = head->next;
int n,m;
int i,j;
printf("请输入要删除学生的学号!\n");
scanf("%d",&n);
printf("请认真考虑是否要删除? 是......1,否......2\n");
scanf("%d",&m);
if(m == 1)
{
while(temp2 != NULL)
{
if(n == temp2->student.id)
{
temp1->next =temp2->next;
}
temp1 = temp1->next ;
temp2 = temp2->next ;
}
free(temp2);
count--;
printf("删除成功!\n");
}
else if(m == 2)
{
return;
}
}
//3.修改学生信息
void Change(struct Node *head)
{
struct Node *temp = head;
int n;
printf("请输入要修改学生的学号!\n");
scanf("%d",&n);
while(temp != NULL)
{
if(n == temp->student.id)
{
printf("请输入修改后的学生姓名!\n");
scanf("%s",temp->student.name);
printf("请输入修改后的学生性别!\n");
scanf("%s",temp->student.sex);
printf("请输入修改后的学生年龄!\n");
scanf("%d",&temp->student.age);
printf("请输入修改后的学生成绩!\n");
scanf("%f",&temp->student.score);
}
temp = temp->next ;
}
}
//4.查看单个学生信息
void Find(struct Node *head)
{
struct Node *temp = head;
int n,num;
char str[20]= {0};
int flag = 0;
printf("**********请选择查询方式!***********\n");
printf("**********1.通过学号***********\n");
printf("**********2.通过姓名***********\n");
printf("*******************************\n");
scanf("%d",&num);
if(num == 1)
{
printf("请输入要查看学生的学号!\n");
scanf("%d",&n);
while(temp != NULL)
{
if(n == temp->student.id)
{
flag = 1;
printf("该学生信息为:\n");
printf("学号\t姓名\t性别\t年龄\t成绩\n");
printf("%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
}
temp = temp->next ;
}
}
else if(num == 2)
{
printf("请输入要查看学生的姓名!\n");
scanf("%s",str);
while(temp != NULL)
{
if(0 ==strcmp(str,temp->student.name))
{
flag = 1;
printf("该学生信息为:\n");
printf("学号\t姓名\t性别\t年龄\t成绩\n");
printf("%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
}
temp = temp->next ;
}
}
if(flag == 0)
{
printf("查无此人,返回主菜单!\n");
}
}
//5.学生信息排序
void Rank(struct Node *head)
{
int sum = 0;
struct Node *temp=head->next;
struct Node *temp1=head->next;
struct Node *temp2;
struct Stu stu;
printf("**********请选择排序方式!***********\n");
printf("**********1.通过成绩***********\n");
printf("**********2.通过学号***********\n");
printf("*******************************\n");
scanf("%d",&sum);
if(sum == 1)
{
printf("按成绩由高到低排序为:\n");
for(;temp1->next !=NULL;temp1=temp1->next)
{
for(temp2 = temp1->next; temp2 !=NULL; temp2=temp2->next)
{
if(temp1->student.score < temp2->student.score)
{
stu=temp1->student;
temp1->student=temp2->student;
temp2->student=stu;
}
}
}
}
else if(sum == 2)
{
printf("按学号排序为:\n");
for(;temp1->next !=NULL;temp1=temp1->next)
{
for(temp2 = temp1->next; temp2 !=NULL; temp2=temp2->next)
{
if(temp1->student.id > temp2->student.id)
{
stu=temp1->student;
temp1->student=temp2->student;
temp2->student=stu;
}
}
}
}
printf("学号\t姓名\t性别\t年龄\t成绩\n");
while(temp != NULL)
{
printf("%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
temp = temp->next;
}
}
//6.遍历学生信息
void Print(struct Node *head)
{
printf("共有%d个学生信息\n",count);
printf("学号\t姓名\t性别\t年龄\t成绩\n");
struct Node *temp = head->next;
while(temp != NULL)
{
printf("%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
temp = temp->next;
}
}
//7.插入学生信息
void Charu(struct Node *head)
{
struct Node *temp = head->next;
int n,flag = 0;
printf("请输入想要插入的学号后边!\n");
scanf("%d",&n);
while(temp != NULL)
{
if(n == temp->student.id)
{
flag = 1;
struct Node *new2 = (struct Node *)malloc(sizeof(struct Node));
printf("请输入要插入的学生学号!\n");
scanf("%d",&new2->student.id);
printf("请输入要插入的学生姓名!\n");
scanf("%s",new2->student.name);
printf("请输入要插入的学生性别!\n");
scanf("%s",new2->student.sex);
printf("请输入要插入的学生年龄!\n");
scanf("%d",&new2->student.age);
printf("请输入要插入的学生成绩!\n");
scanf("%f",&new2->student.score);
new2->next = temp->next ;
temp->next = new2;
printf("该学生信息插入成功!\n");
count++;
}
temp = temp->next ;
}
if(flag == 0)
{
printf("没有此学生,插入错误!\n");
return;
}
return;
}
//保存学生信息
void Save(struct Node *head)
{
FILE *fp = fopen("student.txt", "w+");
fprintf(fp,"共有%d个学生信息\n",count);
fprintf(fp,"学号\t姓名\t性别\t年龄\t成绩\n");
struct Node *temp = head->next;
while(temp != NULL)
{
fprintf(fp,"%d\t%s\t%s\t%d\t%f\n",temp->student.id,temp->student.name,temp->student.sex,temp->student.age,temp->student.score);
temp = temp->next;
}
fclose(fp);
}
//加载学生信息
void Load(struct Node *head)
{
struct Node *end = head;
FILE *fp = fopen("student.txt", "a+");
if(fgetc(fp)==EOF)
{
printf("文件为空\n");
return;
}
else
{
fseek(fp,-1,1);
fscanf(fp,"共有%d个学生信息\n",&count);
fscanf(fp,"学号\t姓名\t性别\t年龄\t成绩\n");
while(fgetc(fp)!=EOF)
{
fseek(fp,-1,1);
struct Node *new3 = (struct Node *)malloc(sizeof(struct Node));
fscanf(fp,"%d\t%s\t%s\t%d\t%f\n",&new3->student.id,new3->student.name,new3->student.sex,&new3->student.age,&new3->student.score);
new3->next = NULL;
end->next = new3;
end = new3;
}
fclose(fp);
}
}
文本文件student.txt保存的数据如图所示:
相关文件操作函数补充:
1.fgetc()函数 ---单字符读取
int fgetc(FILE *stream);
返回值:成功返回读取到的字符(实际是char类型)
失败或者读到文件末尾,返回EOF
2. fputc()函数 ---写入单字符
int fputc(int c, FILE *stream);
3.fseek()---文件定位
int fseek(FILE *stream, long offset, int whence);
形参:fopen所返回的文件描述符
offset:long int 整型 -- 光标的偏移量,以whence为基准
+往文件末尾方向偏移
-往文件开头方向偏移
whence:偏移的初始位置
文件头0 (SEEK_SET),
当前位置1(SEEK_CUR),
文件尾2 (SEEK_END))为基准
例:int fseek(fp,0, SEEK_SET); //光标偏移到文件开头