通讯录2.0

退出程序时将链表中的数据存入文件,首位存联系人个数,后面依次存联系人信息。
打开程序时取出文件中数据,根据首位存放的个数,来决定插入链表的节点数。

头文件Txl.h

#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_

enum {CANCEL, ID, NAME, TEL, ADDRESS};
typedef enum {TRUE, FALSE, ERROR} BOOL;

enum {QUIT, ADD, DISPLAY, DELETE, SEARCH, CHANGE, SORT};

typedef struct _Data
{
	int id;						//联系人id
	char name[20];				//联系人姓名
	long tel;					//联系人手机号
	char address[20];			//联系人地址
}Data;

typedef struct _Student
{
	Data data;					//数据域
	struct _Student *next;		//指针域,指向链表的下一个结点
}Student;

typedef struct _List
{
	Student *head;				//头结点
}List;

//创建通讯录
List *Creat_List();

//增加联系人
BOOL add_data(List *ls);

//查找联系人
BOOL search_data(List *ls);

//删除联系人
BOOL delete_data(List *ls);

//修改联系人
BOOL modify_data(List *ls);

//打印通讯录
void Display_List(List *ls);

//保存通讯录到文件
BOOL Save_List(List *ls);

//读取通讯录到程序
BOOL LOAD_List(List *ls);

//销毁通讯录
void Destroy_List(List *ls);



#endif	//_LINK_LIST_H_

函数文件Txl.c

#include "Txl.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int Student_Count = 0;

//创建通讯录
List *Creat_List()
{
	List *ls = (List *)malloc(sizeof(List)/sizeof(char));
	if(NULL == ls)			//创建链表失败,返回NULL
		return NULL;
	
	ls->head = (Student *)malloc(sizeof(Student)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);			//创建头节点失败,先释放链表空间,再返回NULL
		return NULL;
	}
	
	ls->head->next = NULL;	//创建时第一个节点为空
	
	return ls;
}

//输出单个联系人信息到屏幕
void print_Student(Student *student)
{
	if(student == NULL)
		return;
	
	printf("%-8d",student->data.id);
	printf("%-16s",student->data.name);
	printf("%-16ld",student->data.tel);
	printf("%s\n",student->data.address);
}

//输出单个联系人到文件
void fprint_Student(Student *student, int fd)
{
	if(student == NULL)
		return;
	
	int ret = write(fd, &(student->data.id), sizeof(student->data.id));
	if(-1 == ret)
	{
		printf("id写入失败: %d\n", student->data.id);
		return;
	}
	
	ret = write(fd, student->data.name, sizeof(student->data.name));
	if(-1 == ret)
	{
		printf("姓名写入失败: %s\n", student->data.name);
		return;
	}
	
	ret = write(fd, &(student->data.tel), sizeof(student->data.tel));
	if(-1 == ret)
	{
		printf("手机号写入失败: %ld\n", student->data.tel);
		return;
	}
	
	ret = write(fd, student->data.address, sizeof(student->data.address));
	if(-1 == ret)
	{
		printf("住址写入失败: %s\n", student->data.address);
		return;
	}
	
}

//尾插
BOOL Insert_Last(List *ls, Data *data)
{
	if(NULL == ls)
	{
		return ERROR;
	}
	
	Student *stu = (Student *)malloc(sizeof(Student)/sizeof(char));
	if(NULL == stu)
	{
		return ERROR;
	}
	
	stu->data = *data;
	stu->next = NULL;
	
	Student *tmp = ls->head;
	while(tmp->next)
	{
		tmp = tmp->next;
	}
	
	tmp->next = stu;
	
	return TRUE;
}

//增加联系人
BOOL add_data(List *ls)
{
	if(NULL == ls)
		return ERROR;
	
	Data data;
	
	system("clear");
	printf("输入新联系人ID:");
	scanf("%d",&data.id);
	
	printf("输入新联系人姓名:");
	scanf("%s",data.name);
	
	printf("输入新联系人手机号:");
	scanf("%ld",&data.tel);
	
	printf("输入新联系人地址:");
	scanf("%s",data.address);
	
	Insert_Last(ls, &data);
	
	Student_Count++;
	
	return TRUE;
}

//显示所有联系人
BOOL display_data(List *ls)
{
	if(NULL == ls)			//链表不存在,返回ERROR
		return ERROR;
	
	if(ls->head->next == NULL)
	{
		return FALSE;				//链表为空,返回FALSE,通讯录无联系人
	}
	
	Student *tmp = ls->head->next;
	
	system("clear");
	printf("---------------------------------------------------\n");
	printf("id\t");
	printf("name\t\t");
	printf("tel\t\t");
	printf("address\n");
	while(tmp != NULL)
	{
		print_Student(tmp);			//遍历联系人列表,同时打印已有联系人信息
		tmp = tmp->next;
	}
	printf("---------------------------------------------------\n");
	
	return TRUE;
}

//删除联系人
BOOL delete_data(List *ls)
{
	if(NULL == ls)
		return ERROR;
	
	char delete[20];			//删除联系人姓名
	BOOL flag = ERROR;			//标记删除的状态,TRUE删除成功,FALSE删除失败,ERROR要删除的联系人不存在
	
	system("clear");
	printf("请输入删除的联系人姓名:");
	scanf("%s", delete);		//输入要删除的联系人姓名
	
	Student *tmp = ls->head;
	while(tmp->next != NULL)	//遍历链表,直到匹配到要删的联系人姓名
	{
		if(strcmp(tmp->next->data.name, delete) == 0)		//匹配成功
		{
			printf("---------------------------------------------------\n");
			printf("id\t");
			printf("name\t\t");
			printf("tel\t\t");
			printf("address\n");
			print_Student(tmp->next);			//打印匹配到的联系人的所有信息
			printf("---------------------------------------------------\n");
			
			char c = 0;
			printf("确认删除该联系人yes(y)/no(n)\n");
			
			while(c != 'y' && c!= 'n')			//对删除操作进行确认,y确认和n取消,输入其他时要重新输入
			{
				scanf("\n%c", &c);	
				if(c == 'y')
				{
					Student *p = tmp->next;		//删除联系人
					tmp->next  = p->next;
					free(p);					//释放删除联系人节点的空间
					Student_Count--;
					flag = TRUE;				//flag标记删除成功
				}
				else if(c == 'n')
				{
					//如果之前已经删除过其他,不改变flag,依然标记删除成功
					if(flag != TRUE)
					{
						flag = FALSE;			//flag标记删除失败
					}
				}
				else
				{
					printf("输入有误,请重新输入\n");
				}
			}
			
			if(c == 'y')
			{
				//如果选择删除,tmp已经移动到了删除的人后一位,用continue跳过tmp = tmp->next这一步
				continue;
			}
		}
		tmp = tmp->next;
	}
	
	
	return flag;						//返回flag
}

//修改联系人
BOOL modify_data(List *ls)
{
	if(NULL == ls)
		return ERROR;
	
	char modify_name[20];	//要修改的联系人的姓名
	int modify;				//要修改的选项
	BOOL flag = ERROR;		//TRUE修改成功,FALSE修改失败,ERROR要修改的联系人不存在
	
	system("clear");
	printf("请输入要修改的联系人的姓名:");
	scanf("%s", modify_name);		//输入要修改联系人的姓名
	
	Student *tmp = ls->head->next;
	while(tmp != NULL)					//遍历链表,直到匹配到要修改的联系人姓名
	{
		if(strcmp(tmp->data.name, modify_name) == 0)	//匹配成功
		{
			//输出当前匹配到的联系人的所有信息
			printf("---------------------------------------------------\n");
			printf("id\t");
			printf("name\t\t");
			printf("tel\t\t");
			printf("address\n");
			print_Student(tmp);
			printf("---------------------------------------------------\n");
			printf("1.ID\n");
			printf("2.姓名\n");
			printf("3.手机号\n");
			printf("4.家庭地址\n");
			printf("0.放弃修改\n");
			printf("请输入要修改的选项:");
			scanf("%d", &modify);			//输入要修改的选项
			switch(modify)
			{
				case ID:
					printf("将id修改为:\n");
					scanf("%d", &(tmp->data.id));
					flag = TRUE;
					break;
				case NAME:
					printf("将姓名修改为:\n");
					scanf("%s", tmp->data.name);
					flag = TRUE;
					break;
				case TEL:
					printf("将手机号修改为:\n");
					scanf("%ld", &(tmp->data.tel));
					flag = TRUE;
					break;
				case ADDRESS:
					printf("将家庭地址修改为:\n");
					scanf("%s", tmp->data.address);
					flag = TRUE;
					break;
				case CANCEL:
					system("clear");
					if(flag != TRUE)
						flag = FALSE;		//取消修改时flag=FALSE,表示修改失败
					break;
				default:
					printf("输入有误,请重新输入\n");
					break;
			}
		}
		tmp = tmp->next;
	}
	
	return flag;
}

//查找联系人
BOOL search_data(List *ls)
{
	if(NULL == ls)
		return ERROR;
	
	char search[20] = {0};		//查找的联系人姓名
	BOOL flag = FALSE;			//标记是否找到,TRUE为找到,FALSE为没找到
	
	system("clear");
	printf("请输入查找的联系人姓名:");
	scanf("%s", search);
	
	Student *tmp = ls->head->next;
	while(tmp != NULL)
	{
		if(strcmp(tmp->data.name, search) == 0)		//匹配到要查找的联系人姓名
		{
			if(flag != TRUE)			//找到第一个时打印输出格式
			{
				printf("---------------------------------------------------\n");
				printf("id\t");
				printf("name\t\t");
				printf("tel\t\t");
				printf("address\n");
				
				flag = TRUE;			//flag标记为已找到
			}
			print_Student(tmp);			//打印找到的联系人信息
		}
		tmp = tmp->next;				//tmp指向下一个节点
	}
	
	return flag;
}

//保存通讯录
BOOL Save_List(List *ls)
{
	int fd = open("document",  O_WRONLY |  O_TRUNC | O_CREAT, 0766);
	if(-1 == fd)
	{
		return FALSE;
	}
	
	if(NULL == ls)
	{
		return ERROR;
	}

	int ret = write(fd, &Student_Count, sizeof(int));
	
	Student *tmp = ls->head->next;
	
	int i;
	for(i = 0; i < Student_Count; i++)
	{
		fprint_Student(tmp, fd);			//遍历联系人列表,同时打印已有联系人信息
		tmp = tmp->next;
	}
	
	
	close(fd);
	return TRUE;
}

//读取通讯录到程序
BOOL Load_List(List *ls)
{
	int fd = open ("document", O_RDONLY);
	if(-1 == fd)
	{
		return FALSE;
	}
	
	int ret = read(fd, &Student_Count, sizeof(int));
	if(-1 == ret)
	{
		return FALSE;
	}
	
	int i;
	
	Data data;
	for(i = 0; i < Student_Count; i++)
	{
		ret = read(fd, &(data.id), sizeof(data.id));
		if(-1 == ret)
		{
			printf("id读取失败: %d\n", data.id);
			return;
		}
		
		ret = read(fd, data.name, sizeof(data.name));
		if(-1 == ret)
		{
			printf("姓名读取失败: %s\n", data.name);
			return;
		}
		
		ret = read(fd, &(data.tel), sizeof(data.tel));
		if(-1 == ret)
		{
			printf("手机号读取失败: %ld\n", data.tel);
			return;
		}
		
		ret = read(fd, data.address, sizeof(data.address));
		if(-1 == ret)
		{
			printf("住址读取失败: %s\n", data.address);
			return;
		}
		
		Insert_Last(ls, &data);
	}

	
	return TRUE;
}

//销毁通讯录
void Destroy_List(List *ls)
{
	if(NULL == ls)
		return ;
	
	Student *tmp = ls->head;
	while(tmp->next)			//释放链表中各个节点的空间
	{
		Student *p   = tmp->next;
		tmp->next 	 = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

菜单函数menu.c

#include "Txl.h"
#include <stdio.h>
#include <stdlib.h>

//菜单
void menu(List *ls)
{	
	int com = 0;
	BOOL search_flag;
	BOOL delete_flag;
	BOOL modify_flag;
	
	while(1)
	{
		printf("\t**************\n");
		printf("\t*1.增加联系人*\n");
		printf("\t*2.显示联系人*\n");
		printf("\t*3.删除联系人*\n");
		printf("\t*4.查找联系人*\n");
		printf("\t*5.修改联系人*\n");
		printf("\t*0.保存并退出*\n");
		printf("\t**************\n");
		scanf("%d",&com);
		switch(com)
		{
			case ADD:
			{
				if(add_data(ls) == TRUE)
				{
					printf("添加成功!\n");
				}
				else
				{
					printf("添加失败!\n");
				}
				break;
			}	
			case DISPLAY:
			{
				if(display_data(ls) != TRUE)
				{
					system("clear");
					printf("通讯录目前无联系人\n");;
				}
				break;
			}	
			case DELETE:
			{
				delete_flag = delete_data(ls);
				if(delete_flag == TRUE)
				{
					printf("删除成功\n");
				}
				else if(delete_flag == FALSE)
				{
					printf("删除失败\n");
				}
				else if(delete_flag == ERROR)
				{
					printf("要删除的联系人不存在\n");
				}
				break;
			}	
			case SEARCH:
			{
				search_flag = search_data(ls);
				if(search_flag == TRUE)
				{
					printf("---------------------------------------------------\n");
				}
				if(search_flag != TRUE)
				{
					printf("未查找到该联系人\n");
				}
				break;
			}	
			case CHANGE:
			{
				modify_flag = modify_data(ls);
				if(modify_flag == TRUE)
				{
					printf("修改成功\n");
				}
				else if(modify_flag == FALSE)
				{
					printf("修改失败\n");
				}
				else if(modify_flag == ERROR)
				{
					printf("要修改的联系人不存在\n");
				}
				break;
			}
			case QUIT:
				Save_List(ls);
				printf("谢谢使用!\n");
				return ;
			default:
				printf("请输入正确的选项\n");
				break;
		}
		
	}
}

main函数

#include <stdio.h>
#include "Txl.h"


int main()
{
	List *ls = Creat_List();
	
	system("clear");
	if(NULL == ls)
	{
		printf("创建通讯录失败\n");
	}
	else
	{
		printf("创建通讯录成功\n");
	}
	
	Load_List(ls);
	menu(ls);
	
	
	Destroy_List(ls);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值