简介:一个简单的学生信息管理系统,用纯C语言实现,数据结构是用单链表,可以进自动进行数据的磁盘存储和读取(数据存储是二进制格式)。存储的数据只有姓名、学号、成绩。此程序包含了C语言一般链表使用的(增、删、改、查)所有动作和C语言文件存储的一般形式,可作为C语言初学者练习链表和文件知识的不错例子。
程序运行后自动从磁盘读取数据,把历史数据存储在链表里,然后再程序里可以对链表进行操作,程序正常退出时,会把数据自动存储到磁盘,以二进制文本形式。
下面是程序的全部源代码:
程序使用了三个文件:
1)list.h文件:功能函数接口
#pragma once #ifndef LIST_H_ #define LIST_H_ #include<stdbool.h> typedef struct { char name[10]; //姓名 float grade; //成绩 int number; //学号 }Item; //链表节点 typedef struct node { Item item; struct node*next; }Node; typedef Node * List; void menu(void); void InitializeList(List*plist); //初始化链表 bool ListIsEmpty(const List*plist); bool ListIsFull(const List*plist); void ReadList(List*plist);//从文件读入数据 void WriteList(const List*plist);//写进文件 void ListItemCount(const List*plist); //统计数量 void ListSearch(const List*plist);//查找 void ListInsertItem(List*plist);//插入项目 void ListUpdate(const List*plist);//修改 void ListDeleteItem(List*plist);//删除 void show(const List *plist); //输出 void EmptyTheList(List*plist); //清空 #endif // !LIST_H_
2)list.c文件:接口函数具体实现
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include"list.h" void menu(void) { printf("\n\n\n\n\n\n"); puts("\t\t|-------------学生管理里系统------------|"); puts("\t\t|\t 1.输入成绩. |"); puts("\t\t|\t 2.修改成绩. |"); puts("\t\t|\t 3.删除信息. |"); puts("\t\t|\t 4.输出信息. |"); puts("\t\t|\t 5.查询信息. |"); puts("\t\t|\t 6.显示学生数量. |"); puts("\t\t|\t other number is quit. |"); puts("\t\t|---------------------------------------|"); puts("\t\t\t\tchose(1-6):"); } void InitializeList(List*plist) //初试化链表 { *plist = NULL; } bool ListIsEmpty(const List*plist) //查看链表是否是空的 { if (*plist == NULL)return true; else return false; } bool ListIsFull(const List*plist) //查看能链表是否满了 { List pt; bool full; pt = (List)malloc(sizeof(Node)); if (pt == NULL)full = true; else full=false; free(pt); return full; } void ReadList(List*plist) //从文件中读取历史数据 方案1 { puts("正在获取历史数据..."); List current; List pre; FILE* fp; while ((fp = fopen("student.dat", "rb")) == NULL) { fprintf(stderr, "Can't open students.dat file"); exit(1); } rewind(fp); while (!feof(fp)) { current = (List)malloc(sizeof(Node)); if (current == NULL) { puts("No memory!"); exit(EXIT_FAILURE); } current->next = NULL; fread(&(current->item), sizeof(Item), 1, fp); if (feof(fp)) { free(current);break; } if (*plist == NULL) *plist= current; else pre->next = current; pre = current; } fclose(fp); puts("历史数据已经获取."); } //void ReadList(List*plist) //从文件中读取历史数据 方案2 //{ // puts("正在获取历史数据..."); // List current; // List pre = NULL; // FILE* fp; // while ((fp = fopen("student.dat", "rb")) == NULL) // { // fprintf(stderr, "Can't open students.dat file"); // exit(1); // } // rewind(fp); // while (1) // { // current = (List)malloc(sizeof(Node)); // if (current == NULL) // { // puts("No memory!"); // exit(EXIT_FAILURE); // } // if (!fread(&(current->item), sizeof(Item), 1, fp)) // { // free(current); // break; // } // if (*plist == NULL) // *plist = current; // else // pre->next = current; // current->next = NULL; // pre = current; // } // fclose(fp); // puts("历史数据已经获取."); //} void WriteList(const List*plist) //存储数据 { List ptr=*plist; puts("正在存储数据..."); FILE*fp; while ((fp = fopen("student.dat", "wb")) == NULL) { fprintf(stderr, "Can't open students.dat file"); exit(2); } while (ptr != NULL) { fwrite(&(ptr->item), sizeof(Item), 1, fp); ptr = ptr->next; } puts("存储数据成功!"); fclose(fp); } void ListItemCount(const List*plist) //学生数目 { List pt = *plist; unsigned int n=0; while (pt != NULL) { n++; pt = pt->next; } printf("This list have %d students.", n); } void ListSearch(const List*plist) //查找 { List pt = *plist; int number; int flag=1; //标记 puts("Please enter this sudent's number:"); scanf("%d", &number); while (pt != NULL&&flag) { if (pt->item.number == number) { printf("This student name is %s\n,number is %d\n,grade is %f.\n", pt->item.name, pt->item.number, pt->item.grade); flag = 0; //找到标记为0 } else pt = pt->next; } if (flag)printf("No found!"); } void ListInsertItem(List*plist) //输入信息 { List pt=*plist; List pre; List r; int number; if (ListIsFull(plist)) { puts("This list is full."); return; } puts("Please enter number:"); scanf("%d", &number); while (pt != NULL) { if (pt->item.number == number) { puts("This list have this number,please inpit other number."); return; } else { pre = pt; pt = pt->next;} } r = (List)malloc(sizeof(Node)); if (r == NULL) { puts("NO memory!"); exit(3); } r->next = NULL; if (*plist == NULL) *plist = r; else pre->next = r; (r->item).number = number; puts("Please enter this student's name:"); while (getchar() != '\n')continue; gets((r->item).name); puts("Please enter this student's grade:"); scanf("%f", &(r->item.grade)); } void ListUpdate(const List*plist) //修改 { List pt = *plist; int number; int flag = 1; puts("Please enter this student's number:"); scanf("%d", &number); while (pt != NULL&&flag) { if (pt->item.number == number) { puts("Please enter name:"); gets(pt->item.name); puts("Please enter grade:"); scanf("%f", &pt->item.grade); flag = 0; } else pt = pt->next; } if (flag)puts("Don't find this number!"); } void ListDeleteItem(List*plist) //删除 { List pt = *plist; List pr = *plist; int number; int flag=1; puts("Please enter this student's number:"); scanf("%d", &number); while (pt != NULL&&flag) { if (pt->item.number == number) { if (pt == *plist) { *plist = pt->next; free(pt); } else { pr->next = pt->next; free(pt); } flag = 0; } else { pr = pt; pt = pt->next; } } if (flag)puts("No find this student!"); } void show(const List *plist) //输出 { List pt = *plist; if (pt == NULL)puts("This list is empty!"); else while (pt != NULL) { puts("Here is the students list:"); printf("Name is :%s\nNumber is :%d\nGrade is :%f\n", pt->item.name,pt->item.number,pt->item.grade); pt = pt->next; } } void EmptyTheList(List*plist) //清空链表 { List pt = *plist; while (*plist != NULL) { pt =(*plist)->next; free(*plist); *plist = pt; } }
3)student.c函数:主函数
#include<stdio.h> #include<stdlib.h> #include"list.h" int main(void) { List students; int n; InitializeList(&students); if (ListIsFull(&students)) { fprintf(stderr, "NO memory!"); exit(1); } ReadList(&students); menu(); //菜单列表 while (scanf("%d", &n)==1) { while (getchar() != '\n')continue; switch (n) { case 1:ListInsertItem(&students);break; //插入 case 2:ListUpdate(&students);break; //修改 case 3:ListDeleteItem(&students);break; //删除 case 4:show(&students);break; //输出 case 5:ListSearch(&students);break; //查询 case 6:ListItemCount(&students);break; //显示学生数量 default:puts("Bye!");WriteList(&students);EmptyTheList(&students);exit(1); //退出 } menu(); } getchar(); return 0; }
注意:要存储数据必须正常退出,不然不能存储数据。
作者:Wnlife 2018.5.24