赞
踩
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- #define FILE_NAME "student.csv"
-
- #define RD_ID (1<<0)
- #define RD_NAME (1<<1)
- #define RD_SCORE (1<<2)
-
- //描述1个学生的属性
- struct student
- {
- int ID;
- char name[20];
- float score;
- };
- //创建链表的节点数据结构
- struct node
- {
- struct student data;//该节点的数据域
- struct node *next;//该节点的指针域
- };
-
- void GetInfo(struct student *p,unsigned char flag);
- int menu(void); //菜单函数声明
- int add(struct node *p); //添加
- int del(struct node *p); //删除
- int change(struct node *p); //修改
- int find(struct node *p); //查找
- void all_pri(struct node *p); //打印所有
- //int quit(void); //退出
- int save(struct node *p); //保存
- void read(struct node *p); //读取保存的文件
- struct node *head = NULL; //指向头节点的指针变量
- static int Add1(struct node *p,struct student temp);
- int close(struct node *p1);
-
- int main()
- {
- int num=0;
- read(head);
- while(1)
- {
- num = menu();
- switch(num)
- {
- case 1:add(head);break;
- case 2:del(head);break;
- case 3:change(head);break;
- case 4:find(head);break;
- case 5:all_pri(head);break;
- case 6:save(head);return 0;
- }
- }
- }
-
-
- int menu(void)
- {
- int num;
- printf("\t\t*****欢迎进入学生管理系统*****\n");
- printf("\t\t***** 1 添加学生 ***** \n");
- printf("\t\t***** 2 删除学生 ***** \n");
- printf("\t\t***** 3 修改学生 ***** \n");
- printf("\t\t***** 4 查找学生 ***** \n");
- printf("\t\t***** 5 打印所有信息 ***** \n");
- printf("\t\t***** 6 保存并退出学生系统 ***** \n");
- printf("请输入选项:");
- scanf("%d",&num);
- return num;
- }
- /******************************************
- int add(struct node *p)
- {
- //1.开辟新的节点,使用new指向该新的节点
- struct node *new = malloc(sizeof(struct node));
- //2.1给节点的数据域赋值
- GetInfo(&new->data,RD_ID|RD_NAME|RD_SCORE);
- //2.2给节点的指针域赋值
- new->next = NULL;
- //3.把新的节点添加到链表中去
- //3.1 链表为空
- if(head == NULL)
- {
- head = new;
- return 0;
- }
- else//尾插法
- {
- while(p->next != NULL)
- {
- p = p->next;
- }
- //把新节点添加到链表最后节点的后面
- p->next = new;
- return 0;
- }
- }
- ******************************************/
-
-
- int add(struct node *p)
- {
- //1.开辟新的节点,使用new指向该新的节点
- struct node *new = malloc(sizeof(struct node));
- //2.1给节点的数据域赋值
- GetInfo(&new->data,RD_ID|RD_NAME|RD_SCORE);
- //2.2给节点的指针域赋值
- new->next = NULL;
- //3.把新的节点添加到链表中去 -- 中间插入
- //3.1 链表为空
- if(head == NULL)
- {
- head = new;
- return 0;
- }
- //3.2 查找位置,进行插入
- while(p != NULL)
- {
- if(p->data.ID < new->data.ID)
- {
- //后续节点为空,直接插入后面
- if(p->next == NULL)
- {
- p->next = new;
- return 0;
- }
- else if(p->next->data.ID > new->data.ID)
- {
- new->next = p->next;
- p->next = new;
- return 0;
- }
- }
- else if(p == head)
- {
- new->next = head;
- head = new;
- return 0;
- }
- p = p->next;
- }
-
- }
-
- /*
- 删除链表中某个节点
- p1 -- 链表头
- 返回值: 0 -- 成功
- >0 -- 失败
- 1 -- 链表为空
- 2 -- 链表中查询不到
- */
- int del(struct node *p)
- {
- if(p == NULL) //空链表
- {
- return 1;
- }
- struct student temp={0}; //定义一个结构体数组
- GetInfo(&temp,RD_ID); //输入要删除的ID
- struct node *del = NULL;
- //定义一个结构体指针,用来保存要删除节点的首地址
-
- //1.判断是否是第一个节点
- if(p->data.ID == temp.ID)
- {
- del = p;
- head = del->next;
- free(del);
- return 0;
- }
- //第2个节点开始
- while(p->next != NULL) //寻找到最后一个结点
- {
- if(p->next->data.ID == temp.ID)
- {
- del = p->next; //将被删结点的地址给del
- p->next = del->next; //被删结点的下个地址给p的next
- free(del); //释放被删结点
- return 0;
- }
- p = p->next;
- }
- printf("无名之辈,不足挂齿\n");
- return 2;
- }
-
- int change(struct node *p)
- {
- struct student temp = {0}; //初始化结构体数组
- GetInfo(&temp,RD_ID|RD_NAME);//输入你想要修改的学生信息的学号
- while(p != NULL)
- {
- if(p->data.ID == temp.ID)
- {
- if(strcmp(p->data.name,temp.name)==0)
- {
- GetInfo(&temp,RD_ID|RD_NAME|RD_SCORE);
- //输入想要修改的信息
- p->data = temp;
- return 0;
- }
-
- }
- p = p->next;
- }
- printf("查无此人\n");
- return 1;
- }
-
- int find(struct node *p)
- {
- struct student temp = {0}; //保存要查找的信息
- GetInfo(&temp,RD_ID); //输入要查找学生的学号
- while(p != NULL) //循环比较学号
- {
- if(p->data.ID == temp.ID)
- {
- printf("找到该学生,信息如下:\n");
- printf("%d\t",p->data.ID);
- printf("%s\t",p->data.name);
- printf("%f\n",p->data.score);
- return 0;
- }
- p = p->next;
- }
- printf("查无此人\n");
- return 1;
- }
-
- void all_pri(struct node *p)
- {
- printf("打印所有学生信息操作……\n");
- printf("学号\t姓名\t成绩\n");
- while(p != NULL)
- {
- printf("%d\t",p->data.ID);
- printf("%s\t",p->data.name);
- printf("%f\n",p->data.score);
- p = p->next;
- }
- }
-
-
- /*
- flag = 相应的选项是否允许输入
- [0]位 -- no_flag 1--允许输入 0 -- 不允许输入
- [1]位 -- name_flag 1--允许输入 0 -- 不允许输入
- [2]位 -- sex_flag 1--允许输入 0 -- 不允许输入
- */
- void GetInfo(struct student *p,unsigned char flag)
- {
- if(flag & (1<<0))
- {
- printf("请输入学号:");
- scanf("%d",&p->ID);
- }
- if(flag & (1<<1))
- {
- printf("请输入姓名:");
- scanf("%s",p->name);
- }
- if(flag &(1<<2))
- {
- printf("请输入成绩:");
- scanf("%f",&p->score);
- }
- }
-
-
-
-
- int save(struct node *p) //保存
- {
- FILE *fp = fopen(FILE_NAME,"w");
- fprintf(fp,"学号,姓名,分数\n");
- if(p == NULL) //链表为空
- {
- perror("文件打开失败");
- return 1;
- }
- while(p != NULL)
- {
- fprintf(fp,"%d,",p->data.ID);
- fprintf(fp,"%s ,",p->data.name);
- fprintf(fp,"%.2f\n",p->data.score);
- p = p->next;
- }
- fclose(fp);
- return 0;
- }
-
- /**************************************************
- void read(struct node *p)
- {
- FILE *fp = fopen("data.txt","a+");
- if (fp == NULL)
- {
- perror("fopen");
- return ;
- }
- struct node *new = NULL,*end = p;
- while (fgetc(fp) != -1)
- {
- fseek(fp,-1,1);//光标位置
- new = malloc(sizeof(struct node));
- fscanf(fp,"ID: %d\t 姓名: %s\t\t成绩: %f\t\n",&new->data.ID,new->data.name,&new->data.score);
- new->next = NULL;
- end->next = new;
- end = new;
- }
- fclose(fp);
- //return ;
- }
- *************************************************/
-
- void read(struct node *p)
- {
- //1.打开 FILE_NAME r
- FILE *fp = fopen(FILE_NAME,"r");
- //2.往链表中添加新的数据
- //2.1 偏移文件指针 -- 跳过列名
- fseek(fp,sizeof("学号,姓名,性别,分数"),SEEK_SET);
- //2.2 读取文件信息 -- 判断文件是否到最后
- struct student temp={0};
- int res = 0;
- while(1){
- memset(&temp,0,sizeof(temp));
- res = fscanf(fp,"%d,",&temp.ID);
- res = fscanf(fp,"%s",temp.name);
- res = fscanf(fp,"%f",&temp.score);
- if(res == EOF){
- break;
- }
- //2.3 往链表中添加
- Add1(p,temp);
- p = head;//p1从新值指向链表头
- }
- //3.关闭文件
- fclose(fp);
- }
-
- static int Add1(struct node *p,struct student temp)
- {
- //1.开辟新的节点,使用pnew指向该新的节点
- struct node *new = malloc(sizeof(struct node));
- //2.1给节点的数据域赋值
- new->data = temp;
- //2.2给节点的指针域赋值
- new->next = NULL;
- //3.把新的节点添加到链表中去 -- 中间插入
- //3.1 是否为空链表
- if(head == NULL){
- head = new;
- return 0;
- }
- //3.2 查找位置,进行插入
- while(p != NULL){
- if(p->data.ID < new->data.ID)
- {
- //后续节点为空,直接插入后面
- if(p->next == NULL){
- p->next = new;
- return 0;
- }else if(p->next->data.ID > new->data.ID){
- new->next = p->next;
- p->next = new;
- return 0;
- }
- }else if(p == head){
- new->next = head;
- head = new;
- return 0;
- }
- p = p->next;
- }
- }
- int close(struct node *p1)
- {
- printf("系统正在关闭\n");
- save(p1);
- printf("系统关闭完成\n");
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。