C语言链表实现通讯录
基于链表实现通讯录
功能
- 增加联系人
- 删除联系人
- 查找联系人
- 保存通讯录到指定磁盘
- 读取存在磁盘的通讯录信息
学过链表还是较容易看懂
代码如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define path "D:\\adbook.txt"
//通讯录文件存储位置选择
typedef struct node
{
char name[20];
char number[20];
char job[20];
struct node *next;
} Node;
//通讯录链表的节点结构:名字,号码,工作(由于号码只考虑看,用字符串省空间
Node *InitList()
{
Node *head;
head = (Node *)malloc(sizeof(Node));
head->next = NULL;
return head;
}
//初始化通讯录链表的根节点
void enter(Node *head, int *length);
//录入:1;若无提示则提示并询问
void del(Node *head, int *length);
//删除:2;查询到,回车删除
void list(Node *head);
//显示:3;显示通讯录
void search(Node *head);
//查询:4;输入名字在,存在则显示
void save(Node *head, int *sign);
//保存:5;进入保存界面,按回车保存,数据输入文件,显示Saveing file
void load(Node *head, int *length, int *sign);
//加载:6;将数据从磁盘加载到链表中
void create_file()
{
FILE *fp;
fp = fopen(path, "a");
fclose(fp);
}
/*
定义一个函数创建空的txt文件,因为在load函数那使用fopen的r读取。
若采用a/a+或w/w+等,会导致读进乱码。
所以load只负责读取,另外创建一个create函数负责保证文件存在
*/
int main()
{
Node *head;
head = InitList();//初始化链表头
create_file();
int length = 0;//在插入联系人时需要用到长度信息
int sign = 0;//用于标记本次运行是否读取磁盘(是否使用load函数),来选择不同的存储方式,在save处解释
char key;//为什么不用int型,因为int如果输入其他非数字的东西,会死循环(害怕运行者刁难)
//但带来的问题就是要处理scanf缓冲区数据的问题
char ch; //用于清楚缓冲区数据
do
{
printf("\n");
printf("\t\t\t\t*=================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 欢迎使用清河通讯录! *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t|==================================|\n");
printf("\t\t\t\t| 1--录入联系人信息 |\n");
printf("\t\t\t\t| 2--删除联系人信息 |\n");
printf("\t\t\t\t| 3--显示通讯录信息 |\n");
printf("\t\t\t\t| 4--查询联系人信息 |\n");
printf("\t\t\t\t| 5--保存联系人信息 |\n");
printf("\t\t\t\t| 6--加载通讯录信息 |\n");
printf("\t\t\t\t| 0--退出 |\n");
printf("\t\t\t\t|==================================|\n");
printf("\t\t\t\t 请输入你的选项:");
scanf("%c", &key);
while ((ch = getchar()) != EOF && ch != '\n')
; //清除缓冲区的内容
switch (key)
{
case '0':
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* Bye Bye *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
break;
case '1':
enter(head, &length);
break;
case '2':
del(head, &length);
break;
case '3':
list(head);
break;
case '4':
search(head);
break;
case '5':
save(head, &sign);
break;
case '6':
load(head, &length, &sign);
break;
default:
printf("\n\t\t\t\t !!!请重新选择正确的选项!!!");
}
} while (key != '0');
return 0;
}
void enter(Node *head, int *length)
{
Node *node, *end;
end = head;
node = (Node *)malloc(sizeof(Node));
if (head->next == NULL)
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 通讯录为空。 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 是否需要添加新的联系人 *\n");
printf("\t\t\t\t* 0.是 1.否 *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t 请输入你的选项:");
int count = 0;
scanf("%d", &count);
if (!count)
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* 请输入:名字 号码 工作: *\n");
printf("\t\t\t\t* 注:三者之间请空格隔开 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t 请输入相关信息:");
scanf("%s%s%s", node->name, node->number, node->job);
char c;
c = getchar();
end->next = node;
node->next = NULL;
}
}
else
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* 请输入:名字 号码 工作: *\n");
printf("\t\t\t\t* 注:三者之间请空格隔开 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t 请输入相关信息:");
scanf("%s%s%s", node->name, node->number, node->job);
for (int i = 0; i < *length; i++)
end = end->next;
end->next = node;
node->next = NULL;
}
*length = *length + 1;
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 联系人成功已添加 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
};
void del(Node *head, int *length)
{
char del_name[100];
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 请输入要删除的联系人名字: *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t*请输入相关信息:");
scanf("%s", del_name);
char c;
c = getchar(); //这里需要用c“吃掉”scanf输入时的回车,避免影响之后的“确认”操作
Node *node, *d_node;
d_node = head->next;
node = head;
for (int i = 0; i < *length; i++)
{
if (strcmp(d_node->name, del_name) == 0)
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 您确定要删除此人吗? *\n");
printf("\t\t\t\t* 点击 Enter 确定删除操作 *\n");
printf("\t\t\t\t* 输入 b 取消删除操作 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t*请输入相关信息:");
c = getchar();
if (c == '\n')
{
node->next = d_node->next;
free(d_node);
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 删除成功 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
*length = *length - 1;
return;
}
else
{
c = getchar();
return;
}
}
node = node->next;
d_node = d_node->next;
}
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 查无此人 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
};
void list(Node *head)
{
if (head->next == NULL)
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 通讯录为空 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
}
else
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t*姓名 电话 工作 *\n");
while (head->next != NULL)
{
head = head->next;
printf("\t\t\t\t %-12s %-10s %s\n", head->name, head->number, head->job);
}
printf("\t\t\t\t*==================================*\n");
}
};
void search(Node *head)
{
Node *node;
node = head->next;
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 请输入要查找的名字 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
printf("\n");
printf("\t\t\t\t*请输入相关信息:");
char s_name[100];
scanf("%s", s_name);
while (node)
{
if (strcmp(node->name, s_name) == 0)
{
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t %-12s %-10s %s", node->name, node->number, node->job);
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
return;
}
node = node->next;
}
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 查无此人 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
};
void save(Node *head, int *sign)
{
Node *node;
node = head->next;
FILE *fp;
if (*sign)
{
fp = fopen(path, "w");
}
else
{
fp = fopen(path, "a");
}
while (node)
{
fprintf(fp, "%s %s %s%s", node->name, node->number, node->job, "\n");
node = node->next;
}
fclose(fp);
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 数据已保存到磁盘 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
};
void load(Node *head, int *length, int *sign)
{
FILE *fp = NULL;
fp = fopen(path, "r");
Node *node, *end;
end = head;
for (int i = 0; i < *length; i++)
end = end->next;
while (1)
{
if (feof(fp))
break;
node = (Node *)malloc(sizeof(Node));
memset(node, '\0', sizeof(Node));
fscanf(fp, "%s %s %s\n", node->name, node->number, node->job);
if (strlen(node->name) == 0)
break;
node->next = end->next;
end->next = node;
end = node;
*length = *length + 1;
};
end->next = NULL;
fclose(fp);
printf("\n");
printf("\t\t\t\t*==================================*\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t* 磁盘内容加载完毕 *\n");
printf("\t\t\t\t* *\n");
printf("\t\t\t\t*==================================*\n");
*sign = 1;
};

浙公网安备 33010602011771号