一个简单的C语言程序——通讯录

结合目前所学的一些C语言知识,我写了如下的一个通讯录程序,可以实现新建联系人,删除联系人,查找联系人,修改联系人,打印全部联系人,清空全部联系人以及联系人排序。话不多说,我们来看代码
重要模块

#include
#include
#include
#define MAXNUM 100
typedef struct PersonInfo{
  char name[100];
  char sex[10];
  int age;
  char phone[100];
  char address[100];
} PersonInfo;
typedef struct addressbook{
  PersonInfo persons[MAXNUM+1];
  int size;//体现有效元素
} addressbook;

成员变量写好后,我们就要初始化,初始化函数如下

//此处参数设为指针类型
//1.结构体作为函数参数的时候,需要进行开背参数而结构体占据内存可能比较大,参数写成指针类型能降低拷贝开销
//2.初始化函数内部需要修稿结构体变量的内容,我们需要在函数内部修改同时影响到外部
void Init(addressbook* addr)//初始化
{
  addr->size = 0;
  for(int i=0;i<MAXNUM+1;i++){
    strcpy(addr->persons[i].name,"");
    strcpy(addr->persons[i].sex,"");
    addr->persons[i].age=0;
    strcpy(addr->persons[i].phone,"");
    strcpy(addr->persons[i].address,"");
  }
}

初始化完后,我们需要建立一个菜单,来供用户选择,代码如下

int menu()
{
  printf("=====================\n");
  printf("1. 新增联系人\n");
  printf("2. 删除联系人\n");
  printf("3. 查找联系人\n");
  printf("4. 修改联系人\n");
  printf("5. 打印全部联系人\n");
  printf("6. 清空全部联系人\n");
  printf("7. 排序全部联系人\n");
  printf("0. 退出\n");
  printf("=====================\n");
  int choice =0;
  scanf("%d",&choice);
  return choice;
}

新建联系人
上述我们知道,该通讯录是由结构体来实现的所以,新建联系人的时候我们需要判断是否在有效元素内,以及每次新建一个人后都需要将有效元素+1。代码如下

void AddPersonInfo(addressbook* addr_book)//新建联系人
{
  printf("新增联系人\n");
  if(addr_book->size>=MAXNUM){
    printf("通讯录已满");
    return ;
  }
  PersonInfo* info =&addr_book->persons[addr_book->size];
  printf("请输入联系人姓名:");
  scanf("%s",info->name);
  printf("请输入联系人性别(man/woman):");
  scanf("%s",info->sex);
  printf("请输入联系人年龄:");
  scanf("%d",&info->age);
  printf("请输入联系人电话:");
  scanf("%s",info->phone);
  printf("请输入联系人住址:");
  scanf("%s",info->address);
  addr_book->size++;
  printf("新增联系人成功\n");
}

删除联系人
删除联系人的时候呢,我所采用一个最简单的方法,将最后一个有效联系人的所有信息覆盖到你所需要删除的联系人的所有信息,虽然这样做序号会改变,但是我们想想通讯录中只要有这个人,不论在什么位置,都可以找到他。除此之外,每当删除一个人后,我们的有效元素就要减1。这里我用了序号删除或者姓名删除,具体代码如下

void DelPersonInfor(addressbook* addr_book)
{
  printf("删除联系人\n");
  printf("请选择删除方式:\n");
  printf("1.序号删除 2.姓名删除");
  int choice = 0;
  scanf("%d",&choice);
  if(choice==1){
    if(addr_book->size<=0){//判断有效元素是否合法
      printf("通讯录为空!删除失败");
      return ;
    }
    int id = 0;
    printf("输入所要删除的序号:");
    if(id<0||id>addr_book->size){
      printf("输入的id非法,删除失败");
      return ;
    }
    scanf("%d",&id);
    PersonInfo* last_info = &addr_book->persons[addr_book->size-1];
    PersonInfo* to_delete = &addr_book->persons[id];
    *to_delete=*last_info;
    addr_book->size--;
  }
  if(choice==2){
    int i =0;
    char Name[100];
    printf("请输入所需要删除的联系人的姓名:");
    scanf("%s",Name);
    while(1){
      PersonInfo* info=&addr_book->persons[i];
      if(i==addr_book->size){
        printf("查无此人\n");
        break;
      }
      if(strcmp(info->name,Name)==0){
        printf("找到了\n");
        PersonInfo* nlast_info = &addr_book->persons[addr_book->size-1];
        PersonInfo* nto_delete = &addr_book->persons[i];
        *nto_delete=*nlast_info;
        addr_book->size--;
        printf("删除成功\n");
        break;
      }
      i++;
    }
  }
}

查找指定联系人
这个模块比较简单,在这里我只写了姓名查找,遍历整个通讯录,找到所需要找的姓名,打印即可,代码如下

void FindPersonInfo(addressbook* addr_book)//查找指定联系人
{
  printf("查找指定联系人\n");
  printf("请输入要超找的联系人姓名:");
  char name[100]={0};
  scanf("%s",name);
  for(int i=0;i<addr_book->size;i++){
    PersonInfo* info = &addr_book->persons[i];
    if(strcmp(name,info->name)==0){
      printf("[%d] 姓名:%s 性别:%s 年龄:%d 电话:%s 住址:%s\n",i,info->name,info->sex,info->age,info->phone,info->address);
    }
  }
}

修改指定联系人的信息
有新建联系人的模块后,我们知道,修改联系人信息也是很好实现的,这里需要注意的是,用户可能指向修改一个地方或有不需要修改的地方,这时我们就要为用户提供这种服务,可以全部修改,也可以只修改某处信息。代码如下。

void ModifyPersonInfo(addressbook* addr_book)//修改指定联系人信息
{
  //修改指定序号的联系人的姓名或者电话
    if(addr_book->size<=0){
      printf("通讯录为空!修改失败\n");
      return;
    }
    int id=0;
    printf("请输入需要修改的联系人的序号:");
    scanf("%d",&id);
    if(id<0||id>=addr_book->size){
      printf("输入的序号非法!修改失败\n");
      return;
    }
    PersonInfo* info = &addr_book->persons[id];
    printf("请输入修改后的姓名(*表示不变):");
    char name[1024]={0};
    scanf("%s",name);
    if(strcmp(name,"*")!=0){
      strcpy(info->name,name);
    }
    printf("请输入修改后的性别(*表示不变):");
    char sex[50]={0};
    scanf("%s",sex);
    if(strcmp(sex,"*")!=0){
      strcpy(info->sex,sex);
    }
    printf("请输入修改后年龄(*表示不变):");
    int age = 0;
    scanf("%d",&age);
    if(strcmp((age+"0"),"*")!=0){
      info->age=age;
    }
    printf("请输入修改后的电话(*表示不变):");
    char phone[1024]={0};
    scanf("%s",phone);
    if(strcmp(phone,"*")!=0){
      strcpy(info->phone,phone);
    }
    printf("请输入修改后的住址(*表示不变):");
    char address[1024]={0};
    scanf("%s",address);
    if(strcmp(address,"*")!=0){
      strcpy(info->address,address);
    }
    printf("修改成功\n");
}

打印所有联系人信息
这个模块是最简单的,遍历所有通讯录并且打印即可。代码如下

void PrintAllPersonInfo(addressbook* addr_book)//打印所有联系人信息
{
  for(int i = 0;i<addr_book->size;i++){
    PersonInfo* info = &addr_book->persons[i];
    printf("[%d] 姓名:%s 性别:%s 年龄:%d 电话:%s 住址:%s\n",i,info->name,info->sex,info->age,info->phone,info->address);
  }
  printf("当前共打印%d条通讯录\n",addr_book->size);
}

删除所有联系人信息
删除时,只需要将有效元素个数变为0个即可,值得注意的是,我们可以给用户二次选择的服务,即需要考虑到用户不小心按了删除所有联系人的数字。代码如下

void ClearPerson(addressbook* addr_book)//删除所有联系人
{
  printf("删除全部记录!\n");
  printf("您真的要删除吗?Y/N\n");
  char choice[1024]={0};
  scanf("%s",choice);
  if(strcmp(choice,"Y")==0){
    addr_book->size=0;
    printf("删除成功!\n");
  }
  else{
    printf("删除指令已取消\n");
  }
}

联系人排序
这里我是通过strcmp函数来实现的,是让联系人升序排序,选择的排序方法也是较为简单的为冒泡排序。具体代码如下

void SequencePerson(addressbook* addr_book)//所有联系人排序
{
  for(int i =0;i<addr_book->size;i++){
    for(int j=i;j<addr_book->size;j++){
      if(strcmp(addr_book->persons[i].name,addr_book->persons[j].name)>0){
        PersonInfo* info1 = &addr_book->persons[i];
        PersonInfo* info2 = &addr_book->persons[j];
        PersonInfo* info3 = &addr_book->persons[addr_book->size];
        *info3 = *info1;
        *info1 = *info2;
        *info2 = *info3;
      }
    }
  }
  printf("所有联系人排序成功!\n");
}

到这里,所有的函数模块就已经结束,加上主函数,一个较为完整的通讯录就诞生啦!
如果读者们有好的建议或优化的地方,欢迎留言讨论。所有代码如下

#include
#include
#include
#define MAXNUM 100
typedef struct PersonInfo{
  char name[100];
  char sex[10];
  int age;
  char phone[100];
  char address[100];
} PersonInfo;
typedef struct addressbook{
  PersonInfo persons[MAXNUM+1];
  int size;//体现有效元素
} addressbook;
void Init(addressbook* addr)//初始化
{
  addr->size = 0;
  for(int i=0;i<MAXNUM+1;i++){
    strcpy(addr->persons[i].name,"");
    strcpy(addr->persons[i].sex,"");
    addr->persons[i].age=0;
    strcpy(addr->persons[i].phone,"");
    strcpy(addr->persons[i].address,"");
  }
}
int menu()
{
  printf("=====================\n");
  printf("1. 新增联系人\n");
  printf("2. 删除联系人\n");
  printf("3. 查找联系人\n");
  printf("4. 修改联系人\n");
  printf("5. 打印全部联系人\n");
  printf("6. 清空全部联系人\n");
  printf("7. 排序全部联系人\n");
  printf("0. 退出\n");
  printf("=====================\n");
  int choice =0;
  scanf("%d",&choice);
  return choice;
}
void AddPersonInfo(addressbook* addr_book)
{
  printf("新增联系人\n");
  if(addr_book->size>=MAXNUM){
    printf("通讯录已满");
    return ;
  }
  PersonInfo* info =&addr_book->persons[addr_book->size];
  printf("请输入联系人姓名:");
  scanf("%s",info->name);
  printf("请输入联系人性别(man/woman):");
  scanf("%s",info->sex);
  printf("请输入联系人年龄:");
  scanf("%d",&info->age);
  printf("请输入联系人电话:");
  scanf("%s",info->phone);
  printf("请输入联系人住址:");
  scanf("%s",info->address);
  addr_book->size++;
  printf("新增联系人成功\n");
}
void DelPersonInfor(addressbook* addr_book)
{
  printf("删除联系人\n");
  printf("请选择删除方式:\n");
  printf("1.序号删除 2.姓名删除");
  int choice = 0;
  scanf("%d",&choice);
  if(choice==1){
    if(addr_book->size<=0){
      printf("通讯录为空!删除失败");
      return ;
    }
    int id = 0;
    printf("输入所要删除的序号:");
    if(id<0||id>addr_book->size){
      printf("输入的id非法,删除失败");
      return ;
    }
    scanf("%d",&id);
    PersonInfo* last_info = &addr_book->persons[addr_book->size-1];
    PersonInfo* to_delete = &addr_book->persons[id];
    *to_delete=*last_info;
    addr_book->size--;
  }
  if(choice==2){
    int i =0;
    char Name[1024];
    printf("请输入所需要删除的联系人的姓名:");
    scanf("%s",Name);
    while(1){
      PersonInfo* info=&addr_book->persons[i];
      if(i==addr_book->size){
        printf("查无此人\n");
        break;
      }
      if(strcmp(info->name,Name)==0){
        printf("找到了\n");
        PersonInfo* nlast_info = &addr_book->persons[addr_book->size-1];
        PersonInfo* nto_delete = &addr_book->persons[i];
        *nto_delete=*nlast_info;
        addr_book->size--;
        printf("删除成功\n");
        break;
      }
      i++;
    }
  }
}
void FindPersonInfo(addressbook* addr_book)
{
  printf("查找指定联系人\n");
  printf("请输入要超找的联系人姓名:");
  char name[100]={0};
  scanf("%s",name);
  for(int i=0;i<addr_book->size;i++){
    PersonInfo* info = &addr_book->persons[i];
    if(strcmp(name,info->name)==0){
      printf("[%d] 姓名:%s 性别:%s 年龄:%d 电话:%s 住址:%s\n",i,info->name,info->sex,info->age,info->phone,info->address);
    }
  }
}
void ModifyPersonInfo(addressbook* addr_book)
{
  //修改指定序号的联系人的姓名或者电话
    if(addr_book->size<=0){
      printf("通讯录为空!修改失败\n");
      return;
    }
    int id=0;
    printf("请输入需要修改的联系人的序号:");
    scanf("%d",&id);
    if(id<0||id>=addr_book->size){
      printf("输入的序号非法!修改失败\n");
      return;
    }
    PersonInfo* info = &addr_book->persons[id];
    printf("请输入修改后的姓名(*表示不变):");
    char name[1024]={0};
    scanf("%s",name);
    if(strcmp(name,"*")!=0){
      strcpy(info->name,name);
    }
    printf("请输入修改后的性别(*表示不变):");
    char sex[50]={0};
    scanf("%s",sex);
    if(strcmp(sex,"*")!=0){
      strcpy(info->sex,sex);
    }
    printf("请输入修改后年龄(*表示不变):");
    int age = 0;
    scanf("%d",&age);
    if(strcmp((age+"0"),"*")!=0){
      info->age=age;
    }
    printf("请输入修改后的电话(*表示不变):");
    char phone[1024]={0};
    scanf("%s",phone);
    if(strcmp(phone,"*")!=0){
      strcpy(info->phone,phone);
    }
    printf("请输入修改后的住址(*表示不变):");
    char address[1024]={0};
    scanf("%s",address);
    if(strcmp(address,"*")!=0){
      strcpy(info->address,address);
    }
    printf("修改成功\n");
}
void PrintAllPersonInfo(addressbook* addr_book)
{
  for(int i = 0;i<addr_book->size;i++){
    PersonInfo* info = &addr_book->persons[i];
    printf("[%d] 姓名:%s 性别:%s 年龄:%d 电话:%s 住址:%s\n",i,info->name,info->sex,info->age,info->phone,info->address);
  }
  printf("当前共打印%d条通讯录\n",addr_book->size);
}
void ClearPerson(addressbook* addr_book)
{
  printf("删除全部记录!\n");
  printf("您真的要删除吗?Y/N\n");
  char choice[1024]={0};
  scanf("%s",choice);
  if(strcmp(choice,"Y")==0){
    addr_book->size=0;
    printf("删除成功!\n");
  }
  else{
    printf("删除指令已取消\n");
  }
}
void SequencePerson(addressbook* addr_book)
{
  for(int i =0;i<addr_book->size;i++){
    for(int j=i;j<addr_book->size;j++){
      if(strcmp(addr_book->persons[i].name,addr_book->persons[j].name)>0){
        PersonInfo* info1 = &addr_book->persons[i];
        PersonInfo* info2 = &addr_book->persons[j];
        PersonInfo* info3 = &addr_book->persons[addr_book->size];
        *info3 = *info1;
        *info1 = *info2;
        *info2 = *info3;
      }
    }
  }
  printf("所有联系人排序成功!\n");
}
int main()
{
  addressbook address_book;
  Init(&address_book);
  //转移表实现
  typedef void(*Func)(addressbook*);
  Func func_table[]={
    NULL,
    AddPersonInfo,
    DelPersonInfor,
    FindPersonInfo,
    ModifyPersonInfo,
    PrintAllPersonInfo,
    ClearPerson,
    SequencePerson,
  };
  while(1){
    //通过这个循环和用户交互
    int choice = menu();
    if(choice<0||choice>=sizeof(func_table)/sizeof(func_table[0])){
      printf("您的输入有误");
      continue;
    }
    if(choice==0){
      printf("goodbye");
      break;
    }
    func_table[choice](&address_book);
  }
  return 0;
}

你可能感兴趣的:(c语言)