带文件存储操作的双向带头结点的单链表通讯录

tongxunlu.h:

#ifndef _TONGXUNLU_H_
#define _TONGXUNLU_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

enum ret_vlu{MALLOC_OK, MALLOC_NO, CREATE_OK, CREATE_NO, EMPTY_OK, EMPTY_NO};

typedef struct contactPerson //带头结点的双向不循环链表
{
	char id[10];
	char name[20];
	char age[3];
	char tel[20];
	char address[20];
	
	struct contactPerson *front;
	struct contactPerson *next;	
}Pnode, *Plink;

FILE * fp;

void Welcome(); //欢迎界面
void Menu(); //菜单
int Is_malloc_ok(Plink person); //判断是否分配内存成功
int Is_empty(Plink person); //判断通讯录是否为空
int Creat_link(Plink *person); //创建通讯录链表并初始化
int Creat_node(Plink *new_node); //创建一个结点并初始化
void AddInfo(Plink person, Plink new_node); //添加联系人信息
void Is_tel_right(char *tel); //检查号码格式是否有误
void Insert_node(Plink person, Plink new_node); //将联系人信息插入到链表中去
void LookInfo(Plink person); //查看通讯录
void FindInfo(Plink person); //查找联系人
Plink FindInfo_id(Plink person); //按id查找联系人
Plink FindInfo_name(Plink person); //按姓名查找联系人
void Is_findinfo(Plink p); //检测是否查询到联系人
void DeleteInfo(Plink person); //删除联系人
void Printinfo(Plink p); //打印联系人信息
void ChangeInfo(Plink person); //修改联系人信息
void SaveInfo(FILE * fp, Plink person, int number); //保存联系人信息到文件中
void ReadInfo(FILE * fp, Plink person, Plink *new_node); //从文件中读取信息到通讯录系统中去
void itoa(int number, char *num); //将整数转换成字符
void Empty_link(Plink person); //清空链表


#endif

tongxunlu.c:

#include "tongxunlu.h"

void Welcome() //欢迎界面
{
	printf("-----------------------------------------------------\n");
	printf("\t\t欢迎使用BK通讯录系统\n");
	printf("\t\t正在加载......\n");
	printf("-----------------------------------------------------\n");
}

void Menu() //菜单
{
	printf("**************************\n");
	printf("\t1.添加用户\n");
	printf("\t2.查看用户\n");
	printf("\t3.搜索用户\n");
	printf("\t4.删除用户\n");
	printf("\t5.修改用户\n");
	printf("\t6.保存信息\n");
	printf("\t7.退出系统\n");
	printf("**************************\n");
}

int Is_empty(Plink person) //判断通讯录是否为空
{
	if (NULL == person->next)
	{
		system("clear");
		printf("通讯录为空!请插入联系人!\n");
		
		return EMPTY_OK;
	}
	
	return EMPTY_NO;
}

int Is_malloc_ok(Plink person) //判断是否分配内存成功;
{
	if (NULL != person)
	{
		return MALLOC_OK;
	}
	
	return MALLOC_NO;
}

int Creat_link(Plink *person) //创建通讯录链表并初始化
{
	*person = (Plink)malloc(sizeof(Pnode));
	
	if (MALLOC_OK != Is_malloc_ok(*person))
	{
		return CREATE_NO;
	}
	
	(*person)->front = NULL; 
	(*person)->next = NULL; 
	
	return CREATE_OK;
}

int Creat_node(Plink *new_node) //创建一个结点并初始化
{
	*new_node = (Plink)malloc(sizeof(Pnode));
	
	if (MALLOC_OK != Is_malloc_ok(*new_node))
	{
		return CREATE_NO;
	}
	
	(*new_node)->front = NULL; 
	(*new_node)->next = NULL; 
	
	return CREATE_OK;
}

void AddInfo(Plink person, Plink new_node) //添加联系人信息
{

	system("clear");
	printf("请输入联系人的信息:(编号 姓名 年龄 手机号码 地址)\n");
	scanf("%s %s %s %s %s", new_node->id, new_node->name, new_node->age, new_node->tel, new_node->address);
	Is_tel_right(new_node->tel);
	Insert_node(person, new_node);
	
	system("clear");
	printf("输入完成!返回主菜单中...\n");
	
}

void Is_tel_right(char *tel) //检查号码格式是否有误
{
	int mark = 0; //创建一个标记,如果号码有误,mark标记为1,然后重新输入
	char *p = tel;
	
	if (11 != strlen(tel)) // 手机号码必须为11位
	{
		mark = 1;
	}
	
	while (*p != '\0') //挨个遍历查询输入的是否正确
	{
		if (*p < '0' || *p > '9')
		{
			mark = 1;
		}
		p++;
	}
	
	if (1 == mark)
	{
		printf("联系人手机号码输入格式有误!请重新输入号码!\n");
		scanf("%s", tel);
		Is_tel_right(tel); //递归调用直到输入无误为止
	}
	//输入无误mark为0不需要处理
}
	
void Insert_node(Plink person, Plink new_node) //将联系人信息插入到链表中去
{
	Plink p = NULL;
	p = person;
	
	while (p->next != NULL)
	{
		p = p->next;
	}
	
	p->next = new_node;
	new_node->front = p;
	new_node->next = NULL;
}

void LookInfo(Plink person) //查看通讯录
{
	system("clear");
	Plink p = NULL;
	p = person->next;
	
	if (EMPTY_NO != Is_empty(person))
	{
		return;
	}
	
	int i = 0;
	while (p != NULL)
	{
		Printinfo(p);
		
		p = p->next;
	}
	
	char mark;
	printf("按任意键输入回车后返回主菜单\n");
	scanf(" %c", &mark);
	system("clear");
	printf("返回主菜单中...\n");
}

void FindInfo(Plink person) //查找联系人
{
	system("clear");
	int choice;
	Plink p = NULL;
	
	if (EMPTY_NO != Is_empty(person))
	{
		return;
	}
	
	while (1)
	{
		
		printf("按1输入id进行查找!\n");
		printf("按2输入姓名进行查找!\n");
		scanf("%d", &choice);
		switch(choice)
		{
		case 1:
			p = FindInfo_id(person);
			Is_findinfo(p);
			
			return;
			
		case 2:
			p = FindInfo_name(person);
			Is_findinfo(p);
			
			return;
		default:
			printf("输入有误!请重新输入!\n");
			printf("返回上一级菜单中...\n");
			sleep(1);
			
			continue;
		}
	}
}

Plink FindInfo_id(Plink person) //按id查找联系人
{
	system("clear");
	char id[10];
	printf("请输入要查询的id:\n");
	scanf("%s", id);
	
	Plink p = NULL;
	p = person->next;
	while (p != NULL)
	{
		if (strcmp(p->id, id) == 0)
		{			
			return p;
		}
		p = p->next;
	}
	
	return p;
}

Plink FindInfo_name(Plink person) //按姓名查找联系人
{
	system("clear");
	char name[20];
	printf("请输入要查询的姓名:\n");
	scanf("%s", name);
	
	Plink p = NULL;
	p = person->next;
	while (p != NULL)
	{
		if (0 == strcmp(p->name, name))
		{		
			return p;
		}
		p = p->next;
	}

	return p;
}

void Is_findinfo(Plink p) //检测是否查询到联系人
{
	if (NULL != p)
	{
		system("clear");
		printf("联系人已查询到:\n");
		Printinfo(p);
			
		char ch;
		printf("按任意键输入回车后返回主菜单!\n");
		scanf(" %c", &ch);
		system("clear");
		printf("返回主菜单中...\n");
	}
	else
	{
		system("clear");
		printf("查无此人!\n");
		printf("返回主菜单中...\n");
	}
}

void DeleteInfo(Plink person) //删除联系人
{
	system("clear");
	if (EMPTY_NO != Is_empty(person))
	{
		return;
	}
	
	Plink p = NULL;
	p = FindInfo_name(person);
	
	if (NULL != p)
	{
		system("clear");
		printf("联系人已查询到:\n");
		Printinfo(p);
		printf("正在删除联系人...\n");
		printf("联系人%s已删除\n", p->name);
		printf("正在返回主菜单...\n");
		sleep(1);
		p->front->next = p->next;
		free(p);
		p = NULL;
	}
	else
	{
		system("clear");
		printf("查无此人!\n");
		printf("返回主菜单中...\n");
	}
}

void ChangeInfo(Plink person) //修改联系人信息
{
	system("clear");
	if (EMPTY_NO != Is_empty(person))
	{
		return;
	}
	
	Plink p = NULL;
	p = FindInfo_name(person);
	
	if (NULL != p)
	{
		system("clear");
		printf("联系人已查询到:\n");
		Printinfo(p);
		printf("请重新输入联系人的信息(编号 年龄 手机号码 地址)\n");
		scanf("%s %s %s %s", p->id, p->age, p->tel, p->address);
		Is_tel_right(p->tel);
		printf("联系人%s已更新\n", p->name);
		printf("正在返回主菜单...\n");
		sleep(1);
	}
	else
	{
		system("clear");
		printf("查无此人!\n");
		printf("返回主菜单中...\n");
	}
}

void itoa(int number, char *num) //将整数转换成字符
{
	int i, length = 1, n;
	n = number;
	while ((n / 10) != 0 )
	{
		length++;
		n = n / 10;
	}
	
	n = number;
	for (i = length - 1; i >= 0; i--)
	{
		num[i] = n % 10 + '0';
		n = n / 10;
	}
}

void SaveInfo(FILE * fp, Plink person, int number) //保存联系人信息到文件中
{
	fseek(fp, 0, SEEK_SET);
	char num[20] = {0};
	itoa(number, num);
	fwrite(num, 20, 1, fp);
	if (number == 0)
	{
		system("clear");
		printf("通讯录为空!请插入联系人!\n");
		printf("返回主菜单中...\n");
		
		return;
	}
	
	Plink p = person->next;
	while (p != NULL)
	{
		fwrite(p->id, 10, 1, fp);
		fwrite(p->name, 20, 1, fp);
		fwrite(p->age, 3, 1, fp);
		fwrite(p->tel, 20, 1, fp);
		fwrite(p->address, 20, 1, fp);
		p = p->next;
	}
	
	system("clear");
	printf("保存成功!\n");
	printf("返回主菜单中...\n");
}

void ReadInfo(FILE * fp, Plink person, Plink *new_node) //从文件中读取信息到通讯录系统中去
{
	fseek(fp, 0, SEEK_SET);
	char num[20] = {0};
	int mark, i;
	fread(num, 20, 1, fp);
	int number = atoi(num);
	for (i = 0; i < number; i++)
	{
		mark = Creat_node(new_node); //创建一个结点直到创建成功为止
		while (mark != CREATE_OK)
		{
			mark = Creat_node(new_node);
		}
		Insert_node(person, *new_node);
		
		fread((*new_node)->id, 10, 1, fp);
		fread((*new_node)->name, 20, 1, fp);
		fread((*new_node)->age, 3, 1, fp);
		fread((*new_node)->tel, 20, 1, fp);
		fread((*new_node)->address, 20, 1, fp);
	}
}

void Empty_link(Plink person) //清空链表
{
	Plink p = NULL;
	p = person->next;
	while (p != NULL)
	{
		person->next = p->next;
		free(p);
		p = NULL;
		p = person->next;
	}
}

void Printinfo(Plink p) //打印联系人信息
{
	printf("id:%s\n", p->id);
	printf("姓名:%s\n", p->name);
	printf("年龄:%s\n", p->age);
	printf("手机号码:%s\n", p->tel);
	printf("地址:%s\n", p->address);	
}

main.c:

#include "tongxunlu.h"

int main()
{
	Plink person = NULL;
	Plink new_node = NULL; 
	char num[20] = {0};
	int number = 0; //用来记录联系人数量
	if ((fp = fopen("person.txt", "r+")) == NULL)
	{
		perror("fopen file1 error!\n");
		
		exit(-1);
	}

	int mark = Creat_link(&person); //创建一个链表直到创建成功为止
	while (mark != CREATE_OK)
	{
		 mark = Creat_link(&person);
	}
	
	fread(num, 20, 1, fp); //读入联系人数量
	fseek(fp, 0, SEEK_SET); 
	number = atoi(num);
	ReadInfo(fp, person, &new_node); //从文件中读取信息到通讯录系统中去
	
	system("clear");
	Welcome();
	int choice;
	
	while(1)
	{	
		sleep(1);
		system("clear");
		Menu();		
		scanf("%d", &choice);
		switch(choice)
		{
		case 1:
			mark = Creat_node(&new_node); //创建一个结点直到创建成功为止
			while (mark != CREATE_OK)
			{
				mark = Creat_node(&new_node);
			}
			AddInfo(person, new_node); //添加联系人信息
			number++;
			
			break;
		case 2:
			LookInfo(person); //查看通讯录
			
			break;
		case 3:
			FindInfo(person); //查找联系人
			
			break;
		case 4:
			DeleteInfo(person); //删除联系人
			number--;
			
			break;
		case 5:
			ChangeInfo(person); //修改联系人信息
			
			break;
		case 6:
			SaveInfo(fp, person, number); //保存联系人信息到文件中
			Empty_link(person); //清空链表
			ReadInfo(fp, person, &new_node); //从文件中读取最新的信息到通讯录系统中去
			
			break;
		case 7:
			system("clear");
			printf("正在退出......期待您的下次使用!\n");
			sleep(1);
			system("clear");
			exit(0);
		default:
			system("clear");
			printf("输入有误,请重新输入!\n");
			sleep(1);
			continue;
		}
	}
	
	fclose(fp);
	
	return 0;
}

makefile:

OBJS=main.o tongxunlu.o
txl:$(OBJS)
	gcc $(OBJS) -o txl
tongxunlu.o:$<
	gcc -c tongxunlu.c
main.o:main.c
	gcc -c main.c
.PHONY:clean
clean:
	rm *.o txl

使用注意:

使用前需要在当前目录里自己创建一个person.txt文件,里面输入0并保存!
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值