使用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;
}

主菜单:

 

目录
相关文章
|
4天前
|
C语言
C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训
C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训
14 0
|
8天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的C语言在线评测系统的详细设计和实现
基于SpringBoot+Vue+uniapp的C语言在线评测系统的详细设计和实现
33 16
|
4天前
|
C语言
C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训
C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训
9 1
|
9天前
|
机器学习/深度学习 搜索推荐 程序员
C语言实现个人通讯录(功能优化)-2
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-2
|
9天前
|
存储 C语言 索引
C语言实现个人通讯录(功能优化)-1
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-1
|
16天前
|
C语言
C语言学习记录——通讯录(静态内存)
C语言学习记录——通讯录(静态内存)
14 2
|
26天前
|
存储 C语言
C语言实现通讯录
C语言实现通讯录
20 2
|
27天前
|
存储 C语言
C语言实验-动态顺序表实现简易通讯录(二)
在这个C语言实验中,你将实现一个简单的通讯录,它使用动态顺序表来存储联系人信息。
28 2
|
16天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的C语言在线评测系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的C语言在线评测系统附带文章和源代码部署视频讲解等
9 0
|
16天前
|
存储 C语言
C语言学习记录——通讯录(动态内存)
C语言学习记录——通讯录(动态内存)
12 0