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并保存!