Linux C/C++ 编程 实现通讯录(结构体)

35 篇文章 0 订阅

欢迎大家来到别爱的CSDN


前言

提示:本文主要实现了简易的通讯录
项目的知识点为:链表的操作,添加节点,遍历,查找。


提示:以下是本篇文章正文内容

一、如何实现简易通讯录?

通讯录是大家入门Linux进行编程练手的一个小项目,大家可以通过我的示例进行自己的通讯录实现。
我的通讯录具体有以下功能
在这里插入图片描述
1.插入数据
2.打印数据
3.删除数据
4.搜索数据
5.保存文件
6.读取文件
然后保存在文件下用gcc编译之后,就可以直接实现本项目。

二、实现思路

1.架构设计

代码如下(示例):

在这里插入图片描述
主要实现三层结构,分别为业务层,接口层,逻辑层。业务层用来实现具体的业务,接口层用来连接逻辑层,方便后期对软件的修改操作。逻辑层的存储部分和功能部分主要都是链表来进行操作的。

2.链表与结构体的设计

代码如下:

struct person
{
	char name[NAME_LENGTH];			//姓名
	char phone[PHONE_LENGTH];		//电话
	
	struct person* next;			//指向下一个节点的指针
	struct person* prev;			//指向上一个节点的指针
};


struct contacts
{
	struct person* people;
	int count;					//计数

};

宏定义如下:

#define NAME_LENGTH 16
#define PHONE_LENGTH 11
#define BUFFER_LENGTH	128
#define MIN_TOKEN_LENGTH 5

#define INFO printf

#define LIST_INSERT(item,list) do{	\
		item->prev = NULL;			\
		item->next = list;			\
	if((list)!=NULL)(list)->prev=item;	\
		(list) = item;				\
}while(0)


#define LIST_REMOVE(item,list)do{	\
		if (item->prev != NULL) item->prev->next = item->next;	\
		if (item->next != NULL) item->next->prev = item->prev;	\
		if (item == list) list = item->next;					\
		item->prev = item->next = NULL;							\
}while(0)

3.架构接口层的设计

代码如下:

int person_insert(struct person** ppeople,struct person* ps){
	if (ps == NULL) return -1;

	LIST_INSERT(ps, *ppeople);

	return 0;
}

int person_delete(struct person** ppeople, struct person* ps) {
	if (ps == NULL) return -1;
	LIST_REMOVE(ps, *ppeople);

	return 0;
}

struct person* person_search(struct person* people, const char* name) {

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		if (!strcmp(name, item->name))
			break;
	}

	return item;
}

int person_traversal(struct person* people) {

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		INFO("name: %s,phone: %s\n", item->name, item->phone);
	}

	return 0;
}

int save_file(struct person* people, const char* filename) {

	FILE* fp = fopen(filename, "w");
	if (fp == NULL)return -1;

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		fprintf(fp, "name: %s,phone: %s\n", item->name, item->phone);
		fflush(fp);
	}

	fclose(fp);

}

int parser_token(char* buffer, int length, char* name, char* phone) {

	if (buffer == NULL)return -1;
	if (length < MIN_TOKEN_LENGTH) return -2;

	int i = 0, j = 0, status = 0;
	for (i = 0; buffer[i] != ','; i++) {
		if (buffer[i] == ' ') {
			status = 1;
		}
		else if (status == 1) {
			name[j++] = buffer[i];
		}
	}

	status = 0;
	j = 0;
	for (; i < length; i++) {
		if (buffer[i] == ' ') {
			status = 1;
		}
		else if (status == 1) {
			phone[j++] = buffer[i];
		}
	}

	INFO("file token: %s -->%s \n", name, phone);

	return 0;
}


int loda_file(struct person** ppeople, int* count, const char* filename) {

	FILE* fp = fopen(filename, "r");
	if (fp == NULL)return -1;

	while (!feof(fp)) {

		char buffer[BUFFER_LENGTH] = { 0 };
		fgets(buffer, BUFFER_LENGTH, fp);
		int length = strlen(buffer);
		INFO("length: %d\n", length);

		char name[NAME_LENGTH] = { 0 };
		char phone[PHONE_LENGTH] = { 0 };

		if (0 != parser_token(buffer, length, name, phone)) {
			continue;
		}

		struct person* p = (struct person*)malloc(sizeof(struct person));
		if (p == NULL)return -2;

		memcpy(p->name, name, NAME_LENGTH);
		memcpy(p->phone, phone, PHONE_LENGTH);

		person_insert(ppeople, p);

		(*count)++;

	}

}

4.业务逻辑的设计

代码如下:

int insert_entry(struct contacts* cts) {

	if (cts == NULL)return -1;

	struct person* p = (struct person*)malloc(sizeof(struct person));
	if (p == NULL) return -2;
	//name
	INFO("Please Input Name: \n");
	scanf("%s", p->name);

	//phone
	INFO("Please Input Phone: \n");
	scanf("%s", p->phone);

	//add
	if (0!=person_insert(&cts->people, p)) {
		free(p);
		return -3;
	}
	cts->count++;
	INFO("Insert Success\n");

	return 0;

}


int print_entry(struct contacts* cts) {

	if (cts == NULL) return -1;

	//cts->people

	person_traversal(cts->people);

}


int delete_entry(struct contacts* cts) {

	if (cts == NULL)return -1;
	//name
	INFO("Please Input Name : \n");
	char name[NAME_LENGTH] = { 0 };
	scanf("%s", &name);

	//person	
	struct person *ps=person_search(cts->people, name);
	if (ps == NULL) {
		INFO("Person don't Exit \n");
		return -2;
	}

	//delete
	person_delete(&cts->people, ps);
	free(ps);

	return 0;
}


int search_entry(struct contacts* cts) {

	if (cts == NULL)return -1;
	//name
	INFO("Please Input Name : \n");
	char name[NAME_LENGTH] = { 0 };
	scanf("%s", &name);

	//search	
	struct person* ps = person_search(cts->people, name);
	if (ps == NULL) {
		INFO("Person don't Exit \n");
		return -2;
	}

	INFO("name: %s,phone: %s\n", ps->name, ps->phone);

	return 0;

}


int save_entry(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Save Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);

	save_file(cts->people, filename);

	return 0;
}


int load_enty(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Load  Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);
	
	loda_file(&cts->people, &cts->count, filename);

	return 0;
}

int save_entry(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Save Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);

	save_file(cts->people, filename);

	return 0;
}


int load_enty(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Load  Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);
	
	loda_file(&cts->people, &cts->count, filename);

	return 0;
}

5.完整代码

代码如下:

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

#define NAME_LENGTH 16
#define PHONE_LENGTH 11
#define BUFFER_LENGTH	128
#define MIN_TOKEN_LENGTH 5

#define INFO printf

#define LIST_INSERT(item,list) do{	\
		item->prev = NULL;			\
		item->next = list;			\
	if((list)!=NULL)(list)->prev=item;	\
		(list) = item;				\
}while(0)


#define LIST_REMOVE(item,list)do{	\
		if (item->prev != NULL) item->prev->next = item->next;	\
		if (item->next != NULL) item->next->prev = item->prev;	\
		if (item == list) list = item->next;					\
		item->prev = item->next = NULL;							\
}while(0)



struct person
{
	char name[NAME_LENGTH];
	char phone[PHONE_LENGTH];
	
	struct person* next;
	struct person* prev;
};


struct contacts
{
	struct person* people;
	int count;

};

enum {
	OPER_INSERT = 1,		//添加
	OPER_PRINT,				//打印
	OPER_DELETE,			//删除
	OPER_SEARCH,			//查找
	OPER_SAVE,				//保存到文件
	OPER_LOAD				//加载
};




//define interface
int person_insert(struct person** ppeople,struct person* ps){
	if (ps == NULL) return -1;

	LIST_INSERT(ps, *ppeople);

	return 0;
}

int person_delete(struct person** ppeople, struct person* ps) {
	if (ps == NULL) return -1;
	LIST_REMOVE(ps, *ppeople);

	return 0;
}

struct person* person_search(struct person* people, const char* name) {

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		if (!strcmp(name, item->name))
			break;
	}

	return item;
}

int person_traversal(struct person* people) {

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		INFO("name: %s,phone: %s\n", item->name, item->phone);
	}

	return 0;
}


int save_file(struct person* people, const char* filename) {

	FILE* fp = fopen(filename, "w");
	if (fp == NULL)return -1;

	struct person* item = NULL;
	for (item = people; item != NULL; item = item->next) {
		fprintf(fp, "name: %s,phone: %s\n", item->name, item->phone);
		fflush(fp);
	}

	fclose(fp);

}

int parser_token(char* buffer, int length, char* name, char* phone) {

	if (buffer == NULL)return -1;
	if (length < MIN_TOKEN_LENGTH) return -2;

	int i = 0, j = 0, status = 0;
	for (i = 0; buffer[i] != ','; i++) {
		if (buffer[i] == ' ') {
			status = 1;
		}
		else if (status == 1) {
			name[j++] = buffer[i];
		}
	}

	status = 0;
	j = 0;
	for (; i < length; i++) {
		if (buffer[i] == ' ') {
			status = 1;
		}
		else if (status == 1) {
			phone[j++] = buffer[i];
		}
	}

	INFO("file token: %s -->%s \n", name, phone);

	return 0;
}


int loda_file(struct person** ppeople, int* count, const char* filename) {

	FILE* fp = fopen(filename, "r");
	if (fp == NULL)return -1;

	while (!feof(fp)) {

		char buffer[BUFFER_LENGTH] = { 0 };
		fgets(buffer, BUFFER_LENGTH, fp);
		int length = strlen(buffer);
		INFO("length: %d\n", length);

		char name[NAME_LENGTH] = { 0 };
		char phone[PHONE_LENGTH] = { 0 };

		if (0 != parser_token(buffer, length, name, phone)) {
			continue;
		}

		struct person* p = (struct person*)malloc(sizeof(struct person));
		if (p == NULL)return -2;

		memcpy(p->name, name, NAME_LENGTH);
		memcpy(p->phone, phone, PHONE_LENGTH);

		person_insert(ppeople, p);

		(*count)++;

	}

}




//end

int insert_entry(struct contacts* cts) {

	if (cts == NULL)return -1;

	struct person* p = (struct person*)malloc(sizeof(struct person));
	if (p == NULL) return -2;
	//name
	INFO("Please Input Name: \n");
	scanf("%s", p->name);

	//phone
	INFO("Please Input Phone: \n");
	scanf("%s", p->phone);

	//add
	if (0!=person_insert(&cts->people, p)) {
		free(p);
		return -3;
	}
	cts->count++;
	INFO("Insert Success\n");

	return 0;

}


int print_entry(struct contacts* cts) {

	if (cts == NULL) return -1;

	//cts->people

	person_traversal(cts->people);

}


int delete_entry(struct contacts* cts) {

	if (cts == NULL)return -1;
	//name
	INFO("Please Input Name : \n");
	char name[NAME_LENGTH] = { 0 };
	scanf("%s", &name);

	//person	
	struct person *ps=person_search(cts->people, name);
	if (ps == NULL) {
		INFO("Person don't Exit \n");
		return -2;
	}

	//delete
	person_delete(&cts->people, ps);
	free(ps);

	return 0;
}


int search_entry(struct contacts* cts) {

	if (cts == NULL)return -1;
	//name
	INFO("Please Input Name : \n");
	char name[NAME_LENGTH] = { 0 };
	scanf("%s", &name);

	//search	
	struct person* ps = person_search(cts->people, name);
	if (ps == NULL) {
		INFO("Person don't Exit \n");
		return -2;
	}

	INFO("name: %s,phone: %s\n", ps->name, ps->phone);

	return 0;

}




int save_entry(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Save Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);

	save_file(cts->people, filename);

	return 0;
}


int load_enty(struct contacts* cts) {

	if (cts == NULL) return -1;

	INFO("Please Input Load  Filename: \n");
	char filename[NAME_LENGTH] = { 0 };
	scanf("%s", filename);
	
	loda_file(&cts->people, &cts->count, filename);

	return 0;
}














void  menu_info() {

	INFO("\n\n******************************************************\n");
	INFO("*****1. Add Person\t\t2. Print People*******\n");
	INFO("*****3. Del Person\t\t4. Search People******\n");
	INFO("*****5. Save Person\t\t6. Load People********\n");
	INFO("*****Other Key for Exiting Program  ******************\n");
	INFO("******************************************************\n\n");
}



int main() {

	//struct contacts cts = { 0 };
	struct contacts* cts = (struct contacts*)malloc(sizeof(struct contacts));
	if (cts == NULL)return -1;

	memset(cts, 0, sizeof(struct contacts));

	while (1) {
		menu_info();
	int select = 0;
	scanf("%d",& select);

	switch (select) {

	case OPER_INSERT:
		insert_entry(cts);
		break;

	case OPER_PRINT:
		print_entry(cts);
		break;

	case OPER_DELETE:
		delete_entry(cts);
		break;

	case OPER_SEARCH:
		search_entry(cts);
		break;

	case OPER_SAVE:
		save_entry(cts);
		break;

	case OPER_LOAD:
		load_enty(cts);
		break;

	default:
		goto exit;

		}
	}

exit:
	free(cts);
	return 0;


}

总结

通过本项目的实现,我了解了一个项目的实现,对其进行了架构设计与需求分析,进行了接口层的实现,逻辑层的实现,业务层的实现。

参考资料

C/C++ Linux高级开发课程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值