使用C语言编写一个通讯录系统

简介: 使用C语言编写一个通讯录系统

层次结构:底层(双向链表)-->接口层-->业务逻辑层(1添加联系人,2打印联系人,3删除联系人,4查找联系人,5保存到文件,6从文件中加载联系人);

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NAME_LENGTH 16
#define PHONE_LENGTH 32
#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)
//end
//联系人结构体
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,//2
  OPER_DELETE,//3
  OPER_SEARCH,//4
  OPER_SAVE,//5
  OPER_LOAD//5
};
//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(item->name,name))//item->name和name相等返回0
    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;//注意:将循环变量定义在外面,避免在Linux环境下编译报错
  for(item=people;item!=NULL;item=item->next){
    fprintf(fp,"name: %s,phone: %s\n",item->name,item->phone);//写到缓存中
    fflush(fp);//从缓存刷新到文件中
  }
  fclose(fp);//关闭文件
  return 0;
}
//解析文件,提取姓名,电话
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,state=0;
  for(i=0;buffer[i]!=',';i++){
    if(buffer[i]==' ')state=1;
    else if(state==1){
      name[j++]=buffer[i];
    }
  }
  state=0,j=0;
  for(;i<length;i++){
    if(buffer[i]==' ')state=1;
    else if(state==1){
      phone[j++]=buffer[i];
    }
  }
  INFO("file token:%s--->%s\n",name,phone);
  return 0;
}
//加载文件,将文件中存在的联系人加载到通讯录
int load_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)++;
  }
  fclose(fp);
  return 0;
}
//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 people
  if(0!= person_insert(&cts->people,p)){
    free(p);
    return -3;
  }
  cts->count ++;
  INFO("Insert success\n");
  return 0;
}
//打印联系人
int traversal_entry(struct contacts*cts){
  if(cts==NULL) return -1;
  person_traversal(cts->people);
  return 0;
}
//删除联系人
int delete_entry(struct contacts*cts){
  if(cts==NULL) return -1;
  //name
  char name[NAME_LENGTH]={0};
  INFO("Please Input name: \n");
  scanf("%s",name);
  //person
  struct person *ps=person_search(cts->people,name);
  if(ps==NULL) {
    INFO("%s don't Exit",name);
    return -2;
  }
  //delete
  person_delete(&cts->people,ps);
  return 0;
}
//查找联系人
int search_entry(struct contacts*cts){
  if(cts==NULL) return -1;
  //name
  char name[NAME_LENGTH]={0};
  INFO("Please Input name: \n");
  scanf("%s",name);
  //person
  struct person *ps=person_search(cts->people,name);
  if(ps==NULL) {
    INFO("%s don't Exit \n",name);
    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 filename:\n");
  char filename[NAME_LENGTH]={0};
  scanf("%s",filename);
  save_file(cts->people,filename);
}
//从文件中加载联系人到通讯录
int load_entry(struct contacts*cts){
  if(cts==NULL)return -1;
  INFO("Please Input filename:\n");
  char filename[NAME_LENGTH]={0}; 
  scanf("%s",filename);
  load_file(&cts->people, &cts->count, filename);
}
//end
//菜单界面
int menu_info(void){
  INFO("\n\n***************************************************\n");
  INFO("*****1.Add Person\t2.Print People*************\n");
  INFO("*****3.Del Person\t4.Search Person************\n");
  INFO("*****5.Save People\t6.Load People**************\n");
  INFO("*****Other Key for Exiting Program*****************\n");
  INFO("***************************************************\n\n");
  return 0;
}
//主函数
int main(){
  struct contacts *cts=(struct contacts*)malloc(sizeof(struct contacts));
  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:
        traversal_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_entry(cts);
        break;
      default:
        goto exit;
    }
  }
  exit:
    free(cts);
    return 0;
}

主菜单:

 

目录
相关文章
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
5天前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
71 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
2月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
32 2
|
2月前
|
存储 编译器 C语言
【C语言】学生管理系统:完整模拟与实现(一)
【C语言】学生管理系统:完整模拟与实现
|
2月前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
2月前
|
测试技术 C语言
【C语言】学生管理系统:完整模拟与实现(三)
【C语言】学生管理系统:完整模拟与实现
|
2月前
|
C语言
【C语言】学生管理系统:完整模拟与实现(二)
【C语言】学生管理系统:完整模拟与实现
|
4月前
|
存储 C语言
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
|
4月前
|
存储 C语言
学生管理系统(C语言简单实现)
这篇文章是关于使用C语言实现一个简单的学生管理系统,包括文件的基本应用、数据结构设计、函数实现以及用户界面交互。
学生管理系统(C语言简单实现)