学生管理系统,添加文件相关操作,实现把数据保存在文件中。
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,"%dt%st%st%dt%fn",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,"%dt%st%st%dt%fn",&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#include #include //学生信息结构体 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,否......2n"); 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,否......2n"); 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("%dt%st%st%dt%fn",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("%dt%st%st%dt%fn",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("%dt%st%st%dt%fn",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("%dt%st%st%dt%fn",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,"%dt%st%st%dt%fn",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,"%dt%st%st%dt%fn",&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); //光标偏移到文件开头



