欢迎大家来到别爱的优快云
前言
提示:本文主要实现了简易的通讯录
项目的知识点为:链表的操作,添加节点,遍历,查找。
提示:以下是本篇文章正文内容
一、如何实现简易通讯录?
通讯录是大家入门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;
}
总结
通过本项目的实现,我了解了一个项目的实现,对其进行了架构设计与需求分析,进行了接口层的实现,逻辑层的实现,业务层的实现。