使用c语言单向链表实现简单学生成绩管理系统
本文优化整个代码框架结构,完善用户可以对系统信息的修改。本例中,使用一系列c语言知识,有利于巩固c语言语法,具体包括结构体,枚举,while循环,switch语句,还有数据结构等内容。
基于上一个内容(使用c语言单向链表实现简单学生成绩管理系统(1))作如下修改。
修改1:实现基于姓名对数据进行修改和删除
简单解释下节点的删除
代码实现
//链表中删除数据--根据姓名
int delete_data(student_msg_t * head,char * name)
{
if(isnull(head))
{
printf("no student msg\n");
return -1;
}
int flag = 0;
student_msg_t * temp_node;
//用于备份要删除的节点地址
temp_node = (student_msg_t*)malloc(sizeof(student_msg_t));
if(temp_node == NULL)
{
printf("create temp node fail\n");
return -1;
}
while(head->next != NULL)
{
if(0 == strncmp(head->next->msg.name,name,strlen(name)))
{
//删除此节点
temp_node = head->next;
head->next = temp_node->next;
free(temp_node);
temp_node = NULL;
flag = 1; //判断找到需要删除的信息
break;
}
else
head = head->next;
}
if(flag == 0)
printf("the list do not have the name\n");
else
printf("delete the name msg is success\n");
return 0;
}
//链表中修改数据--根据姓名
int modify_data(student_msg_t * head,grade_msg_t * grade_msg)
{
if(isnull(head))
{
printf("no student msg\n");
return -1;
}
int flag = 0;
while(head->next != NULL)
{
if(0 == strncmp(head->next->msg.name,grade_msg->name,strlen(grade_msg->name)))
{
//修改此节点
head->next->msg.chinese = grade_msg->chinese;
head->next->msg.math = grade_msg->math;
head->next->msg.english = grade_msg->english;
flag = 1; //判断找到需要删除的信息
break;
}
else
{
head = head->next;
}
}
if(flag == 0)
printf("the list do not have the name\n");
else
printf("modify msg success\n");
return 0;
}
修改2:通过输入控制,选择对数据的操作类型
下面贴上完整的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//个人信息结构体,各科成绩可自定义添加
typedef struct grade_msg
{
char name[16];
char sex;
int chinese;
int math;
int english;
}grade_msg_t;
//链表结构体
typedef struct student_msg
{
grade_msg_t msg;
struct student_msg * next;
}student_msg_t;
//定义操作类型枚举
enum operate_type
{
INSERT_TYPE = 1,
DELETE_TYPE,
PRINTF_TYPE,
MODIFY_TYPE
};
//创建链表头
student_msg_t * create_slist_head()
{
student_msg_t * head;
//申请空间
head = (student_msg_t *)malloc(sizeof(student_msg_t));
if(head == NULL)
{
printf("create slist head fail\n");
return NULL;
}
//初始化
head->next = NULL;
return head;
}
//判断链表中有无数据
//返回1为空,0为非空
int isnull(student_msg_t * head)
{
if(head->next == NULL)
return 1;
else
return 0;
}
//链表头添加数据
int insert_data(student_msg_t * head,grade_msg_t * msg)
{
printf("enter insert msg\n");
student_msg_t * new_node;
new_node = (student_msg_t * )malloc(sizeof(student_msg_t));
if(new_node == NULL)
{
printf("insert,create space fail\n");
return -1;
}
strcpy(new_node->msg.name,msg->name);
new_node->msg.sex = msg->sex;
new_node->msg.chinese = msg->chinese;
new_node->msg.math = msg->math;
new_node->msg.english = msg->english;
new_node->next = head->next;
head->next = new_node;
return 0;
}
//打印所有信息
int printf_list(student_msg_t * head)
{
if(isnull(head))
{
printf("no student msg\n");
return -1;
}
while(head->next != NULL)
{
head = head->next;
printf("name:%s,sex:%c,chinese:%d,math:%d,english:%d\n",head->msg.name,head->msg.sex,head->msg.chinese,head->msg.math,head->msg.english);
}
return 0;
}
//链表中删除数据--根据姓名
int delete_data(student_msg_t * head,char * name)
{
if(isnull(head))
{
printf("no student msg\n");
return -1;
}
int flag = 0;
student_msg_t * temp_node;
temp_node = (student_msg_t*)malloc(sizeof(student_msg_t));
if(temp_node == NULL)
{
printf("create temp node fail\n");
return -1;
}
while(head->next != NULL)
{
if(0 == strncmp(head->next->msg.name,name,strlen(name)))
{
//删除此节点
temp_node = head->next;
head->next = temp_node->next;
free(temp_node);
temp_node = NULL;
flag = 1; //判断找到需要删除的信息
break;
}
else
head = head->next;
}
if(flag == 0)
printf("the list do not have the name\n");
else
printf("delete the name msg is success\n");
return 0;
}
//链表中修改数据--根据姓名
int modify_data(student_msg_t * head,grade_msg_t * grade_msg)
{
if(isnull(head))
{
printf("no student msg\n");
return -1;
}
int flag = 0;
while(head->next != NULL)
{
if(0 == strncmp(head->next->msg.name,grade_msg->name,strlen(grade_msg->name)))
{
//修改此节点
head->next->msg.chinese = grade_msg->chinese;
head->next->msg.math = grade_msg->math;
head->next->msg.english = grade_msg->english;
flag = 1; //判断找到需要删除的信息
break;
}
else
{
head = head->next;
}
}
if(flag == 0)
printf("the list do not have the name\n");
else
printf("modify msg success\n");
return 0;
}
int main(int argc, const char *argv[])
{
student_msg_t * msg_head;
char msg_str[64];
char name_str[16];
int flag;
grade_msg_t insert_msg;
msg_head = create_slist_head();
if(msg_head == NULL)
{
printf("create student msg head fail\n ");
return -1;
}
while(1)
{
printf("input operate flag \n");
printf("1 INSERT_TYPE\n");
printf("2 DELETE_TYPE\n");
printf("3 PRINTF_TYPE\n");
printf("4 MODIFY_TYPE\n");
scanf("%d",&flag);
getchar();
switch(flag)
{
case INSERT_TYPE:
{
//姓名 字符串 性别 字符类型 语数英 整型
printf("please input 姓名[enter] 性别[enter] 语文[enter] 数学[enter] 英语[enter]\n");
//简化信息输入
printf("------------input start------------\n");
scanf("%s",insert_msg.name);
getchar();
scanf("%c",&insert_msg.sex);
getchar();
scanf("%d",&insert_msg.chinese);
getchar();
scanf("%d",&insert_msg.math);
getchar();
scanf("%d",&insert_msg.english);
getchar();
printf("------------input end------------\n");
//插入数据
insert_data(msg_head,&insert_msg);
}
break;
case PRINTF_TYPE:
{
printf("==========printf start==========\n");
if(msg_head -> next != NULL)
printf_list(msg_head);
printf("==========printf end=========\n");
}
break;
case DELETE_TYPE:
{
printf("<delete>please enter delete name\n");
memset(name_str,0,sizeof(name_str));
scanf("%s",name_str);
getchar();
delete_data(msg_head,name_str);
}
break;
case MODIFY_TYPE:
{
printf("<modify>please input modify name\n");
memset(name_str,0,sizeof(insert_msg.name));
scanf("%s",insert_msg.name);
getchar();
scanf("%d",&insert_msg.chinese);
getchar();
scanf("%d",&insert_msg.math);
getchar();
scanf("%d",&insert_msg.english);
getchar();
modify_data(msg_head,&insert_msg);
}
break;
default:
printf("no have the operate type\n");
}
}
return 0;
}
本例是笔者闲暇之余顺手写个一个简单实例(此功能使用sqlite3数据库实现更为简单,有时间再实现),主要是为了巩固下c语言的基本知识点,复习下单向链表,后面还有最后一篇结尾,在程序中加入io操作,保存备份信息到文件,并且可以使程序退出,重新运行可直接载入信息。