一個簡單的C語言程序——通訊錄

結合目前所學的一些C語言知識,我寫了如下的一個通訊錄程序,可以實現新建聯繫人,刪除聯繫人,查找聯繫人,修改聯繫人,打印全部聯繫人,清空全部聯繫人以及聯繫人排序。話不多說,我們來看代碼
重要模塊

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#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<stdio.h>
#include<stdlib.h>
#include<string.h>
#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章