黑马程序员技术交流社区
标题:
C语言 链表通讯录
[打印本页]
作者:
acdd112
时间:
2015-11-28 00:09
标题:
C语言 链表通讯录
本帖最后由 acdd112 于 2015-11-28 09:11 编辑
自己写了个基于链表的通讯录, 算是学完C语言后的自我检测因为将每个函数都写在了单独的一个文件, 所以就分开展示代码
#ifndef Header_h
#define Header_h
#include <stdlib.h>
#include <string.h>
#include "doAdd.h"
#include "doDelete.h"
#include "doUpdate.h"
#include "doList.h"
#include "doSearch.h"
#include "init.h"
#include "input.h"
#include "writeFile.h"
#define NAMELEN 22 //姓名最大长度
#define TELLEN 12 //电话最大长度
#define STRULEN sizeof(Contact) //结构体大小
#define filePath "telbook.data" //数据存储位置
/**
* 定义联系人结构体指针类型
*/
typedef struct Person{
char name[NAMELEN]; //联系然姓名
char telnum[TELLEN]; //联系人电话
struct Person *next; //链接下一个结构体
}Contact;
extern char fno;
extern int tatolContactCount;
extern char BUFFER[];
extern Contact *head;
extern Contact *tail;
extern Contact *location;
extern Contact *delete;
#endif /* Header_h */
复制代码
#include <stdio.h>
#include "Header.h"
int tatolContactCount = 0; //记录联系人总个数
char fno = 0; //用户指令
char BUFFER[100]; //输入缓冲
Contact *head = NULL; //链表头指针
Contact *tail = NULL; //链表尾指针
Contact *location = NULL; //链表定位指针
Contact *delete = NULL; //链表删除指针
int main(int argc, const char * argv[]) {
init(); //数据初始化
printf("****************************\n");
printf("****** 欢迎使用通讯录 ******\n");
printf("****** 1. 添加联系人 ******\n");
printf("****** 2. 删除联系人 ******\n");
printf("****** 3. 修改联系人 ******\n");
printf("****** 4. 查询所有联系人 **\n");
printf("****** 5. 搜索联系人 ******\n");
printf("****** 6. 退出系统 ******\n");
printf("****************************\n");
printf("输入任意键载入系统...\n");
fgets(BUFFER, 10, stdin);
system("clear");
//输入主入口
while (1) {
input();
}
return 0;
}
复制代码
#include "init.h"
#include "Header.h"
/**
初始化函数
- returns: 0 初始化成功
*/
int init()
{
FILE *fp = fopen(filePath, "r"); //文件指针初始化打开数据文件
Contact *new = NULL; //链表指针初始化
//判断是否打开数据文件
if (fp) {
//读取文件中的联系人计数
fread(&tatolContactCount, sizeof(tatolContactCount), 1, fp);
//遍历数据文件
for (int i = 0; i < tatolContactCount; i++) {
new = (Contact *)malloc(STRULEN); //获取新内存空间
fread(new, STRULEN, 1, fp); //将数据文件读入内存
if (head == NULL) {
head = tail = new; //初始化头指针及尾指针
}
else {
tail->next = new; //将数据接入链表
tail = new; //尾指针后移
new->next = NULL;
}
}
printf("通讯录初始化完成!\n");
}
else
{
fp = fopen(filePath, "wb"); //创建数据文件
fwrite(&tatolContactCount, sizeof(tatolContactCount), 1, fp); //写入联系人总人数
printf("通讯录文件创建成功!\n");
}
fclose(fp); //关闭文件指针
return 0;
}
复制代码
#include "writeFile.h"
#include "Header.h"
/**
* 文本输入函数
*
* @return 0 正常退出
*/
int writeFile()
{
FILE *fp = fopen(filePath, "wb"); //以二进制写的形式打开文本
location = head; //将定位指针移至表头
fwrite(&tatolContactCount, sizeof(tatolContactCount), 1, fp); //将联系人总数写至文件头
//遍历链表, 将链表内容写入数据文件
while (location) {
fwrite(location, STRULEN, 1, fp);
location = location->next;
}
fclose(fp); //关闭文件指针
return 0;
}
复制代码
/**
* 功能选择函数
* 1.添加
* 2.删除
* 3.修改
* 4.查询所有
* 5.搜索
* 6.退出
*/
void input()
{
printf("1.添加\t2.删除\t3.修改\t4.查询所有 5.搜索\t6.退出\n");
char name[NAMELEN]; //记录搜索名
printf("请选择1~6之间的功能编号:\n");
scanf("%c", &fno);
fgets(BUFFER, 10, stdin); //输入缓冲
switch (fno) {
case '1':
//执行添加
printf("请输入联系人姓名:\n");
scanf("%21s",name);
fgets(BUFFER, 10, stdin);
doAdd(name);
break;
case '2':
//执行删处
printf("请输入要删除的联系人姓名:\n");
scanf("%21s", name);
fgets(BUFFER, 10, stdin);
doDelete(name);
break;
case '3':
//执行修改
printf("请输入要修改的联系人姓名:\n");
scanf("%21s", name);
fgets(BUFFER, 10, stdin);
doUpdate(name);
break;
case '4':
//执行查看
doList();
break;
case '5':
//执行搜索
printf("请输入查找人姓名:\n");
scanf("%21s", name);
fgets(BUFFER, 10, stdin);
if(!doSearch(name)){
/**
* 当搜索成功, 继续可选操作
* 1.修改 2.删除 3.返回
*/
printf("1.修改\t2.删除\t3.返回\n");
scanf("%c", &fno);
fgets(BUFFER, 10, stdin);
switch(fno){
case '1':
doUpdate(name);
break;
case '2':
doDelete(name);
break;
default:
break;
}
}
break;
case '6':
printf("程序正在退出...\n"); //执行退出
printf("程序已退出!\n");
exit(0);
default:
printf("ERROR! 请重新输入!\n"); //输入出错
break;
}
}
复制代码
#include "doAdd.h"
#include "Header.h"
/**
* 联系人添加函数
*
* @param name 被添加联系人的姓名
*/
void doAdd(char name[]){
//获取新联系人的内存空间
Contact *new = NULL;
new = (Contact *)malloc(STRULEN);
//判断内存空间否获取成功
if (new != NULL) { //当内存空间获取成功
//存入联系人信息
strcpy(new->name,name);
printf("请输入联系人电话:\n");
scanf("%11s",new->telnum);
getchar();
new->next = NULL;
tatolContactCount++; //联系人计数累加
//判断添加的联系人是否为第一组信息
if (head == NULL) { //当数据为第一组信息
tail = head = new; //初始定位头指针和尾指针
}
else //当数据不为第一组信息
{
tail->next = new; //将数据添加在链表尾部
tail = new; //重新定位尾指针
}
writeFile(); //保存数据
printf("联系人添加成功\n\n");
}
else //当内存空间获取失败
{
printf("ERROR!添加失败!\n\n");
}
}
复制代码
作者:
acdd112
时间:
2015-11-28 00:13
本帖最后由 acdd112 于 2015-11-28 09:01 编辑
/**
* 联系人删除函数
*
* @param name 被删除联系人的姓名
*/
void doDelete(char name[]){
location = head; //定位指针初始化
delete = head; //删除指针初始化
//删除指针遍历整个链表
while (delete) {
//判断是否存在联系人的姓名
if (!strcmp(name, delete->name)) { //当前找到该联系人
tatolContactCount--; //联系人计数减一
if (delete == head) { //当联系人为链表首
head = head->next; //将头指针后移
free(delete); //释放被删除联系人的内存空间
writeFile(); //保存数据
printf("删除成功!\n\n");
return;
}
else if (delete == tail) { //当该联系人为链表尾
tail = location; //将尾指针前移
tail->next = NULL;
free(delete); //释放被删除联系人的内存空间
writeFile(); //保存数据
printf("删除成功!\n\n");
return;
}
else { //当联系人在链表内部
location->next = delete->next; //将被删除联系人下一组信息接在其上一组信息尾部
free(delete); //释放被删除联系人的内存空间
writeFile(); //保存数据
printf("删除成功\n\n");
return;
}
}
else { //当前未找到该信息人
location = delete; //后移定位指针(定位指针指向删除指针前一组信息)
delete = delete->next; //后移删除指针
}
}
printf("删除失败!未找到该联系人!\n\n"); //在链表内未找到被删除联系人信息 提示失败
}
复制代码
#include "doList.h"
#include "Header.h"
/**
* 查询所有联系人函数
*/
void doList(){
//判断通讯录内是否有数据
if (head) { //当存在数据
location = head; //初始化定位指针
printf("联系人\t\t电话\n");
while (location) { //遍历链表输出
printf("%s\t\t%s\n", location->name, location->telnum);
location = location->next;
}
printf("\n");
}
else //当不存在数据
{
printf("通讯录为空!\n\n");
}
}
复制代码
#include "doSearch.h"
#include "Header.h"
/**
* 联系人搜索函数
*
* @param name 被搜索联系人姓名
*/
int doSearch(char name[]){
location = head; //初始化定位指针
//遍历链表
while(location) {
//判断是否找到该联系人
if (! strcmp(name, location->name)) { //当前找到该联系人
printf("联系人\t\t电话\n"); //输出该联系人信息
printf("%s\t\t%s\n", name, location->telnum);
return 0;
}
else //当前未找到该联系人
{
location = location->next; //后移定位指针
}
}
printf("未找到您查找的联系人!\n"); //在连表内为找到该联系人 提示
LOOP:
printf("是否要添加该联系人? Y/N"); //提示是否添加该联系人
scanf("%c",&fno);
fgets(BUFFER, 10, stdin); //输入缓冲
switch (fno) {
case 'y':
case 'Y':
doAdd(name); //添加新联系人
return 1;
case 'n':
case 'N':
return 1; //退出
default:
printf("输入错误!\n");
goto LOOP; //输入错误 跳转重新输入
break;
}
}
复制代码
#include "doUpdate.h"
#include "Header.h"
/**
* 联系人修改函数
*
* @param name 被修改联系人姓名
*/
void doUpdate(char name[]){
if (doSearch(name)) //搜索该联系人
return; //当未找到则退出
LOOP: //修改功能选择 1.姓名 2.电话
printf("请选择:\t1.修改联系人姓名\t2.修改联系人电话\n");
scanf("%c", &fno);
fgets(BUFFER, 10, stdin);
switch (fno) {
case '1':
//修改姓名
printf("请输入新的姓名:\n");
scanf("%21s", location->name);
fgets(BUFFER, 10, stdin);
writeFile(); //保存数据
printf("修改成功\n\n");
break;
case '2':
//修改电话
printf("请输入新的电话:\n");
scanf("%11s", location->telnum);
fgets(BUFFER, 10, stdin);
writeFile(); //保存数据
printf("修改成功\n\n");
break;
default:
//输入错误 跳转重新输入
printf("输入错误!\n");
goto LOOP;
break;
}
}
复制代码
做的还不是很完善, 欢迎大家一起学习交流
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2