makefile
main : main.o stu.o llist.o
gcc -Wall -o $@ $^
clean :
rm -rf main *.o
头文件
llist.h
#ifndef __LLIST_H
#define __LLIST_H
enum a
{
HEADINSERT,
TAILINSERT
};
typedef void (llist_print)(const void *data);
typedef int (llist_cmp)(const void *data, const void *cp);
typedef void LLIST;
LLIST *llist_handler(int size);
int llist_insert(LLIST *h, const void *data, int mode);
int llist_delect(LLIST *h, const void *data, llist_cmp cmp);
void *llist_find(LLIST *h, const void *data, llist_cmp cmp);
void *llist_display(LLIST *h, llist_print print);
void *llist_destroy(LLIST *h);
int llist_fetch(LLIST *handler, void *b_data, llist_cmp cmp, void *save);
int llist_output(LLIST *h, void *save);
#endif
stu.h
#ifndef __STU_H
#define __STU_H
#include "llist.h"
struct stu
{
int id;
char name[20];
long int tel;
};
void insert_data(LLIST *handler);
int delect_data(LLIST *handler);
int fetch_data(LLIST *handler);
int find_data(LLIST *handler);
void display_data(LLIST *handler);
void sort_data(LLIST *handler);
int save_data(LLIST *handler);
int read_data(LLIST *handler);
#endif
llist.c
#include
#include
#include <string.h>
#include "llist.h"
struct llist_node
{
struct llist_node *prev;
struct llist_node *next;
char data[0];
};
struct head_node
{
int size;
struct llist_node node;
};
LLIST *llist_handler(int size)
{
struct head_node *handler = NULL;
handler = malloc(sizeof(LLIST));
if(handler == NULL)
return NULL;
handler->size = size;
handler->node.prev = handler->node.next = &handler->node;
return handler;
}
int llist_insert(LLIST *h, const void *data, int mode)
{
struct head_node *handler = h;
struct llist_node *newnode = NULL;
struct llist_node *p = &handler->node;
newnode = malloc(sizeof(struct llist_node) + handler->size);
if(newnode == NULL)
return -1;
memcpy(newnode->data, data, handler->size);
switch(mode)
{
case HEADINSERT : break;
case TAILINSERT : p = p->prev;
break;
default : free(newnode);
break;
}
newnode->next = p->next;
newnode->prev = p->next->prev;
newnode->prev->next = newnode;
newnode->next->prev = newnode;
return 0;
}
struct llist_node *_find(LLIST *h, const void *data, llist_cmp cmp)
{
struct head_node *handler = h;
struct llist_node *cur = NULL;
for(cur = handler->node.next; cur != &handler->node; cur = cur->next)
{
if(cmp(cur->data, data))
return cur;
}
return NULL;
}
void *llist_find(LLIST *h, const void *data, llist_cmp cmp)
{
struct head_node *handler = h;
struct llist_node *find = NULL;
find = _find(handler, data, cmp);
if(NULL == find)
return NULL;
return find->data;
}
int llist_delect(LLIST *h, const void *data, llist_cmp cmp)
{
struct head_node *handler = h;
struct llist_node *find = NULL;
find = _find(handler, data, cmp);
if(NULL == find)
return -1;
find->prev->next = find->next;
find->next->prev = find->prev;
free(find);
}
void *llist_display(LLIST *h, llist_print print)
{
struct head_node *handler = h;
struct llist_node *cur = handler->node.next;
while(cur != &handler->node)
{
print(cur->data);
cur = cur->next;
}
}
void *llist_destroy(LLIST *h)
{
struct head_node *handler = h;
struct llist_node *p = NULL;
struct llist_node *cur = NULL;
for(p = handler->node.next; p != &handler->node; p = p->next)
{
cur = p;
p->next->prev = p->prev;
p->prev->next = p->next;
free(p);
p = cur;
}
free(handler);
}
int llist_fetch(LLIST *h, void *b_data, llist_cmp cmp, void *save)
{
struct head_node *handler = h;
struct llist_node *cur = NULL;
struct llist_node *find = NULL;
find = _find(handler, b_data, cmp);
if(NULL == find)
return -1;
memcpy(save, find->data, handler->size);
find->next->prev = find->prev;
find->prev->next = find->next;
free(find);
}
int llist_output(LLIST *h, void *save)
{
struct head_node *handler = h;
struct llist_node *cur = handler->node.next;
if(cur == &handler->node)
return -1;
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
memcpy(save, cur->data, handler->size);
free(cur);
}
stu.c
#include
#include
#include
#include <string.h>
#include "stu.h"
static int a, ret, b, bnum, num;
static char name[20];
static char bname[20];
static long int tel, lbnum, lnum;
void print(const void *data) //打印函数
{
const struct stu *p = data;
printf("%d %s %ld\n", p->id, p->name, p->tel);
}
int id_cmp(const void *data, const void *cp) //id对比函数
{
const struct stu *p = data;
const int *cur = cp;
return !(p->id - *cur);
}
int tel_cmp(const void *data, const void *cp)
{
const struct stu *p = data;
const long int *cur = cp;
return !(p->tel - *cur);
}
int name_cmp(const void *data, const void *cp) //名字对比函数
{
const struct stu *p = data;
const char *cur = cp;
return !(strcmp(cur, p->name));
}
void insert_data(LLIST *handler) //增加数据函数
{
struct stu data;
struct stu *find = NULL;
system("clear");
printf("请输入学号:\n");
scanf("%d", &num);
find = llist_find(handler, &num, id_cmp);
if(find != NULL)
{
printf("该学号已存在,请核对后从新输入!\n");
sleep(2);
return ;
}
data.id = num;
printf("请输入学生姓名:\n");
scanf("%s", name);
memcpy(data.name, name, 20);
printf("请输入学生电话:\n");
scanf("%ld", &tel);
data.tel = tel;
ret = llist_insert(handler, &data, HEADINSERT);
if(ret < 0)
printf("未能成功添加学生信息。\n");
else
printf("成功添加学生信息。\n");
sleep(2);
}
int delect_data(LLIST *handler) //删除数据函数
{
LEAP :
printf("1.输入学号删除\t2.输入姓名删除\n");
scanf("%d", &b);
if(b == 1)
{
system("clear");
printf("请输入要删除学生的学号:\n");
scanf("%d", &num);
ret = llist_delect(handler, &num, id_cmp);
if(ret < 0)
return -1;
else
printf("成功删除学号为%d的学生信息。\n", num);
}
else if(b == 2)
{
system("clear");
printf("请输入要删除学生的姓名:\n");
scanf("%s", name);
ret = llist_delect(handler, name, name_cmp);
if(ret < 0)
return -1;
else
printf("成功删除姓名为%s的学生信息\n", name);
}
else
{
system("clear");
printf("输入错误,请重新输入\n");
goto LEAP;
}
}
int fetch_data(LLIST *handler) //修改数据函数,修改数据后不排序
{
struct stu save;
LEAP1:
printf("请选择你要修改的信息:\n1.修改学号 2.修改姓名 3.修改电话\n");
scanf("%d", &b);
if(b == 1)
{
system("clear");
printf("请输入你要修改的学号:\n");
scanf("%d", &bnum);
printf("请输入新的学号:\n");
scanf("%d", &num);
ret = llist_fetch(handler, &bnum, id_cmp, &save);
if(ret < 0)
return -1;
else
{
save.id = num;
ret = llist_insert(handler, &save, HEADINSERT);
if(ret < 0)
return -2;
goto PRINT;
}
}
else if(b == 2)
{
system("clear");
printf("请输入你要修改的学生姓名:\n");
scanf("%s", bname);
printf("请输入修改后的学生姓名:\n");
scanf("%s", name);
ret = llist_fetch(handler, bname, name_cmp, &save);
if(ret < 0)
return -1;
else
{
memcpy(save.name, name, 20);
ret = llist_insert(handler, &save, HEADINSERT);
if(ret < 0)
return -2;
else
goto PRINT;
}
}
else if(b == 3)
{
system("clear");
printf("请输入你要修改的电话:\n");
scanf("%ld", &lbnum);
printf("请输入新的电话:\n");
scanf("%ld", &lnum);
ret = llist_fetch(handler, &lbnum, tel_cmp, &save);
if(ret < 0)
return -1;
else
{
save.tel = lnum;
ret = llist_insert(handler, &save, HEADINSERT);
if(ret < 0)
return -2;
goto PRINT;
}
}
else
{
system("clear");
printf("输入错误,请重新输入\n");
goto LEAP1;
}
PRINT:
printf("修改成功!该学生的最新信息为:\n");
print(&save);
}
int find_data(LLIST *handler) //查找数据函数
{
struct stu *find = NULL;
LEAP:
printf("请选择查找方式:\n1.通过学号查找\t2.通过姓名查找\n");
scanf("%d", &a);
if(a == 1)
{
system("clear");
printf("请输入学号:\n");
scanf("%d", &num);
find = llist_find(handler, &num, id_cmp);
if(ret < 0)
return -1;
goto PRINT;
}
else if(a == 2)
{
system("clear");
printf("请输入姓名:\n");
scanf("%s", name);
find = llist_find(handler, name, name_cmp);
if(ret < 0)
return -1;
goto PRINT;
}
else
{
system("clear");
printf("输入错误, 请重新输入!\n");
goto LEAP;
}
PRINT:
printf("已找到!\n");
print(find);
}
void display_data(LLIST *handler) //打印数据函数
{
system("clear");
llist_display(handler, print);
}
void sort_data(LLIST *handler) //排序函数,上限100个
{
struct stu save[100] = {};
struct stu tmp;
struct stu s;
int i = 0, j = 0, a = 0;
for(i = 0; i < 100; i++)
{
ret = llist_output(handler, &s);
if(ret < 0)
break;
memcpy(&save[i], &s, sizeof(struct stu));
}
a = i;
for(i = 0; i < 99; i++)
{
for(j = 0; j < 99 - i; j++)
{
if(save[j].id < save[j+1].id)
{
memcpy(&tmp, &save[j], sizeof(struct stu));
memcpy(&save[j], &save[j+1], sizeof(struct stu));
memcpy(&save[j+1], &tmp, sizeof(struct stu));
}
}
}
for(i = 0; i < a; i++)
{
ret = llist_insert(handler, &save[i], HEADINSERT);
if(ret < 0)
break;
}
printf("排序完成!\n");
sleep(2);
}
int save_data(LLIST *handler) //打印到文件
{
FILE *fp = NULL;
struct stu save;
fp = fopen("data_save", "r+");
if(fp == NULL)
return -1;
while(1)
{
ret = llist_output(handler, &save);
if(ret < 0)
break;
ret = fprintf(fp, "%d\t\t\t%s\t\t\t%ld\n", save.id, save.name, save.tel);
if(ret == EOF)
{
fclose(fp);
perror("fprintf()");
return -1;
}
}
fclose(fp);
fp = NULL;
printf("向文件写入成功!\n");
sleep(2);
}
int read_data(LLIST *handler) //从文件导入链表
{
FILE *fp = NULL;
struct stu save;
fp = fopen("data_save", "r+");
if(fp == NULL)
return -1;
while(1)
{
ret = fscanf(fp, "%d%s%ld", &save.id, save.name, &save.tel);
if(ret == EOF)
{
perror("fprintf()");
break;
}
// print(&save);
llist_insert(handler, &save, HEADINSERT);
}
fclose(fp);
fp = NULL;
printf("文件内容以存入链表!\n");
sleep(2);
}
main.c
#include
#include
#include
#include <string.h>
#include "stu.h"
#include "llist.h"
int main(void)
{
struct stu *data, *save;
char d = 0;
int a = 0, num = 0, ret = 0, b = 0, bnum = 0;
int tel;
FILE *fd = NULL;
LLIST *handler = NULL;
handler = llist_handler(sizeof(struct stu));
if(NULL == handler)
return -1;
/*
fd = fopen("data_save", "w+");
if(fd == NULL)
{
perror("fopen");
return -1;
}
ret = fprintf(fd, "%s\t\t\t%s\t\t\t%s\n", "学号", "姓名", "电话");
if(ret == EOF)
{
fclose(fd);
return -1;
}
fclose(fd);
p = NULL;
*/
while(1)
{
system("clear");
printf("-----------------------------------------------------------\n");
printf("---------------------学生管理系统--------------------------\n");
printf("-----------------------------------------------------------\n");
printf("1.增加数据\t2.删除数据\t3.修改数据\t4.查找数据\n5.打印数据\t6.排序数据\t7.保存文件\t8.读取文件\n9.退出系统\n");
printf("请输入序号操作\n");
scanf("%d", &a);
switch(a)
{
case 9: return 0;
case 1: insert_data(handler);
break;
case 2: ret = delect_data(handler);
if(ret < 0)
printf("删除失败!没有该学生信息。\n");
sleep(2);
break;
case 3: ret = fetch_data(handler);
if(ret == -1)
printf("修改失败!未找到该学生的信息。\n");
else if(ret == -2)
printf("修改失败!\n");
sleep(2);
break;
case 4: ret = find_data(handler);
if(ret < 0)
printf("未找到该学生信息。\n");
sleep(2);
break;
case 5: display_data(handler);
printf("按q退出\n");
getchar();
scanf("%c", &d);
if(d == 'q' || d == 'Q')
break;
case 6: sort_data(handler);
break;
case 7: save_data(handler);
break;
case 8: read_data(handler);
break;
default: printf("输入有误!\n");
sleep(3);
break;
}
}
return 0;
}