C语言从入门到放弃——静态通讯录实现

简介: C语言从入门到放弃——静态通讯录实现

通讯录,一种用于记录通讯地址的书本,在手机,电脑等电子设备中也拥有这种功能,它里面涵盖多种内容,如:姓名、年龄、性别、地址、电话等等,本文就用C语言带大家去实现静态通讯录。我们有几次实现游戏的经验,如扫雷、三子棋,这次同样是分成三个模块,一个用于实现功能,一个用于调用我们实现的功能,一个用于声明。


0a2653c851af460fa595bd959398a8f1.png


一.功能实现


1.打印开始菜单


和三子棋扫雷一样,我们都需要有一个开始菜单,告诉使用者有那些功能,对于我们的通讯录来说,无非就是添加联系人、删除联系人、查找联系人、修改联系人等等,那和三子棋扫雷一样,我们先将这些制作到菜单当中,让使用者选择。


0eacb84100b54626af849e6b562bf92a.png


void menu()
{
  printf("************************************\n");
  printf("*****     1.添加     2.删除    *****\n");
  printf("*****     3.查找     4.修改    *****\n");
  printf("*****     5.显示     6.清空    *****\n");
  printf("*****     7.排序     0.退出    *****\n");
  printf("************************************\n");
}


2.实现选择


选择选择也于扫雷三子棋大同小异,利用dowhile语句来实现多次循环,因为这次选择的功能很多,所以我们采用switch语句。


int input = 0;
do
{
  menu();
  printf("请选择:>");
  scanf("%d", &input);
  switch(input)
  {
  case 1:
  break;
  case 2:
  break;
  case 3:
  break;
  case 4:
  break;
  case 5:
  break;  
    case 6:;
  break;
  case 7:
  break;
  case 0:
  printf("退出通讯录\n");
  break;
  default:
  printf("选择错误,请重新选择\n");
  break;
  }
} while (input);


3.初始化通讯录


我们要实现一个通讯录,那我们这些数据要放在哪里?这里就用到了我们的结构体,我们需要一个结构体,代表一个人的信息,名字,性别,地址这些,那我们还需要确定的是,我们这个通讯录能存多少个人的信息,那我们就假设我们通讯里可以存放一百个人的,那这一百个人,我们去存放的时候怎么知道我们存了多少个人了信息了呢?那这里我们就可以在用一个结构体,里面放我们存放信息的结构体数组,然后一个整型类型的变量,每次存放就加加,删除就减减。


struct addbook
{
  char name[20];
  int age;
  char gen[5];
  char loc[20];
  char ph[12];
};
typedef struct addbooks
{
  struct addbook s[100];
  int sz;
}addb;

那有了这些东西,在没有初始化之前,这些变量和数组里面存放的东西都是未知的,那就需要我们去初始化数组,我们可以直接用第二个结构体类型定义一个变量然后等于0,全初始化成0,我们也可以用一个函数menset来进行我们的初始化,将我们存放信息的数组内的初始化成我们想要的数值。


//初始化通讯录
void init_addbook(addb* ab)
{
  assert(ab);
  ab->sz= 0;
  memset(ab->s, 0, sizeof(ab->s));
}


4.添加、删除等功能实现


(1)添加联系人


添加联系人,这个函数实现逻辑很简单,我们每次添加之前,先确定我们的通讯录是有位置的,所以我们可以先对sz进行一个判断,如果它等于100,就告诉我们通讯录已满,如果没有,就将下标为sz的位置替换成我们想要输入的信息,然后sz加加。


//添加联系人
void add_book(addb* ab)
{
  assert(ab);
  if (ab->sz == MAX)
  {
  printf("通讯录已满");
  return;
  }
  printf("请输入姓名:>");
  scanf("%s", ab->s[ab->sz].name);
  printf("请输入年龄:>");
  scanf("%d", &(ab->s[ab->sz].age)); 
  printf("请输入性别:>");
  scanf("%s", ab->s[ab->sz].gen);
  printf("请输入地址:>");
  scanf("%s", ab->s[ab->sz].loc);
  printf("请输入电话:>");
  scanf("%s", ab->s[ab->sz].ph);
  printf("联系人添加成功\n");
  ab->sz++;
}


(2)删除联系人


删除联系人,我们可以采用输入名字,然后删除的方式,所以我们可以输入一个名字,然后开始对比数组内的每一个名字,相等就进去,跳出循环,然后开始让后面的信息往前面覆盖,最后让sz减减,这里我们要注意,我们后续实现的内容很多都要用到我们的查找,那我们就可以将查找部分分装成一个函数,返回一个整数,如果找不到,就返回-1,找到了,返回此时的下标位置。


//查找
int find_book(addb* ab)
{
  assert(ab);
  char ch[NAME_MAX] = { 0 };
  printf("请输入联系人姓名:>");
  scanf("%s", ch);
  int i = 0;
  for (; i < ab->sz; i++)
  {
  if (!strcmp(ab->s[i].name , ch))
  {
    return i;
  }
  }
  return -1;
}
//删除联系人
void del_book(addb* ab)
{
  assert(ab);
  int find = find_book(ab);
  if (-1==find)
  {
  printf("没有找到此人\n");
  }
  else
  {
  for (; find < ab->sz - 1; find++)
  {
    ab->s[find] = ab->s[find + 1];
  }
  ab->sz--;
  }
}


(3)查找联系人


查找就和我们的删除思路大概一样了,同样调用我们的查找函数,找不到返回-1,告诉我们没有这个人,然后跳出函数,但是后面找到就与删除不一样了,我们将返回下标对应的内容打印出来,就找到了,这里找到联系人之后,信息打印在屏幕上,但是没有提示,对于我们来说可能就有点难确定哪个是哪个,所以这里我们加一个表头,对应每个信息。


//查找联系人
void seek_book(addb* ab)
{
  assert(ab);
  int i = find_book(ab);
  if (i == -1)
  {
  printf("没有找到此联系人\n");
  }
  else
  {
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
    ab->s[i].age,
    ab->s[i].gen,
    ab->s[i].loc,
    ab->s[i].ph);
  }
}


(4)修改联系人


修改也是用我们的查找函数,查找不到就告诉我们没有,然后跳出,查找到了就修改。


//修改联系人
void amend_book(addb* ab)
{
  assert(ab);
  int i = find_book(ab);
  if (i == -1)
  {
  printf("没有找到此联系人\n");
  }
  else
  {
  printf("请输入姓名:>");
  scanf("%s", ab->s[i].name);
  printf("请输入年龄:>");
  scanf("%d", &(ab->s[i].age));
  printf("请输入性别:>");
  scanf("%s", ab->s[i].gen);
  printf("请输入地址:>");
  scanf("%s", ab->s[i].loc);
  printf("请输入电话:>");
  scanf("%s", ab->s[i].ph);
  printf("联系人修改成功\n");
  }
}


(5)显示所有联系人


我们要显示所有联系人,只用打印出我们数组的所有内容就可以,为了方便我们查看,也打印上表头。


//显示全部联系人
void show_book(addb* ab)
{
  assert(ab);
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
  int i = 0;
  for (; i < ab->sz; i++)
  {
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
              ab->s[i].age,
              ab->s[i].gen,
              ab->s[i].loc,
              ab->s[i].ph);
  }
}


(6)清空联系人


清空联系人,也就是和我们的初始化一样,讲数组内容清空。


//初始化通讯录
void init_addbook(addb* ab)
{
  assert(ab);
  ab->sz= 0;
  memset(ab->s, 0, sizeof(ab->s));
}
(7)排序联系人
排序,我们可以用qsort,进行排序,用名字来进行排序。
//qsort
int name_sort(const void* s1, const void* s2)
{
  assert(s1 && s2);
  return strcmp((char*)s1, (char*)s2);
}


二.模块调用


对于我们的通讯录来说,不需要什么逻辑,我们只需要在选择对应的数字的时候,实行对应的功能即可。


源码


addbook.h


#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX 100
#define NAME_MAX 20
#define GEM_MAX 5
#define LOC_MAX 20
#define PH_MAX 12
struct addbook
{
  char name[NAME_MAX];
  int age;
  char gen[GEM_MAX];
  char loc[LOC_MAX];
  char ph[PH_MAX];
};
typedef struct addbooks
{
  struct addbook s[MAX];
  int sz;
}addb;
//功能实现
void init_addbook(addb* ab);//初始化通讯录
void add_book(addb* ab);//添加联系人
void del_book(addb* ab);//删除联系人
int find_book(addb* ab);//查找
void seek_book(addb* ab);//查找联系人
void amend_book(addb* ab);//修改联系人
void show_book(addb* ad);//显示全部联系人
int name_sort(const void* s1, const void* s2);//qsort


addbook.c


#include"addbook.h"
//初始化通讯录
void init_addbook(addb* ab)
{
  assert(ab);
  ab->sz= 0;
  memset(ab->s, 0, sizeof(ab->s));
}
//添加联系人
void add_book(addb* ab)
{
  assert(ab);
  if (ab->sz == MAX)
  {
  printf("通讯录已满");
  return;
  }
  printf("请输入姓名:>");
  scanf("%s", ab->s[ab->sz].name);
  printf("请输入年龄:>");
  scanf("%d", &(ab->s[ab->sz].age)); 
  printf("请输入性别:>");
  scanf("%s", ab->s[ab->sz].gen);
  printf("请输入地址:>");
  scanf("%s", ab->s[ab->sz].loc);
  printf("请输入电话:>");
  scanf("%s", ab->s[ab->sz].ph);
  printf("联系人添加成功\n");
  ab->sz++;
}
//查找
int find_book(addb* ab)
{
  assert(ab);
  char ch[NAME_MAX] = { 0 };
  printf("请输入联系人姓名:>");
  scanf("%s", ch);
  int i = 0;
  for (; i < ab->sz; i++)
  {
  if (!strcmp(ab->s[i].name , ch))
  {
    return i;
  }
  }
  return -1;
}
//删除联系人
void del_book(addb* ab)
{
  assert(ab);
  int find = find_book(ab);
  if (-1==find)
  {
  printf("没有找到此人\n");
  }
  else
  {
  for (; find < ab->sz - 1; find++)
  {
    ab->s[find] = ab->s[find + 1];
  }
  ab->sz--;
  }
}
//查找联系人
void seek_book(addb* ab)
{
  assert(ab);
  int i = find_book(ab);
  if (i == -1)
  {
  printf("没有找到此联系人\n");
  }
  else
  {
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
    ab->s[i].age,
    ab->s[i].gen,
    ab->s[i].loc,
    ab->s[i].ph);
  }
}
//修改联系人
void amend_book(addb* ab)
{
  assert(ab);
  int i = find_book(ab);
  if (i == -1)
  {
  printf("没有找到此联系人\n");
  }
  else
  {
  printf("请输入姓名:>");
  scanf("%s", ab->s[i].name);
  printf("请输入年龄:>");
  scanf("%d", &(ab->s[i].age));
  printf("请输入性别:>");
  scanf("%s", ab->s[i].gen);
  printf("请输入地址:>");
  scanf("%s", ab->s[i].loc);
  printf("请输入电话:>");
  scanf("%s", ab->s[i].ph);
  printf("联系人修改成功\n");
  }
}
//显示全部联系人
void show_book(addb* ab)
{
  assert(ab);
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
  int i = 0;
  for (; i < ab->sz; i++)
  {
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
              ab->s[i].age,
              ab->s[i].gen,
              ab->s[i].loc,
              ab->s[i].ph);
  }
}
//qsort
int name_sort(const void* s1, const void* s2)
{
  assert(s1 && s2);
  return strcmp((char*)s1, (char*)s2);
}


test.c


#include"addbook.h"
void menu()
{
  printf("************************************\n");
  printf("*****     1.添加     2.删除    *****\n");
  printf("*****     3.查找     4.修改    *****\n");
  printf("*****     5.显示     6.清空    *****\n");
  printf("*****     7.排序     0.退出    *****\n");
  printf("************************************\n");
}
int main()
{
  int input = 0;
  addb ab;
  init_addbook(&ab);
  do
  {
  menu();
  printf("请选择:>");
  scanf("%d", &input);
  switch(input)
  {
  case 1:
    add_book(&ab);
    break;
  case 2:
    del_book(&ab);
    break;
  case 3:
    seek_book(&ab);
    break;
  case 4:
    amend_book(&ab);
    break;
  case 5:
    show_book(&ab);
    break;
  case 6:
    init_addbook(&ab);
    break;
  case 7:
    qsort(&ab, ab.sz, sizeof(ab.s[0]),name_sort);
    break;
  case 0:
    printf("退出通讯录\n");
    break;
  default:
    printf("选择错误,请重新选择\n");
    break;
  }
  } while (input);
  return 0;
}
相关文章
|
1天前
|
安全 编译器 C语言
C++入门1——从C语言到C++的过渡
C++入门1——从C语言到C++的过渡
14 2
|
1天前
|
存储 Java 编译器
初识C语言1——C语言入门介绍
初识C语言1——C语言入门介绍
12 1
|
1天前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
2月前
|
C语言
C语言------程设设计入门
这篇文章是C语言程序设计的入门教程,涵盖了C程序的实现过程、VC集成开发环境的使用、基本数据类型的使用、格式控制字符的作用,以及通过示例代码演示了如何使用printf()函数输出不同类型的数据。
C语言------程设设计入门
|
2月前
|
存储 搜索推荐 算法
【C语言】C语言—通讯录管理系统(源码)【独一无二】
【C语言】C语言—通讯录管理系统(源码)【独一无二】
|
2月前
|
存储 数据可视化 C语言
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
|
2月前
|
NoSQL Java 编译器
C语言从入门到精通该怎样学?
持续学习与实践:编程是一门需要不断学习和实践的技能,要保持对新技术和新知识的敏感性,并持续进行编程实践。
44 1
|
3月前
|
存储 Java C语言
【C语言入门】初识C语言:掌握编程的基石
【C语言入门】初识C语言:掌握编程的基石
57 4
【C语言入门】初识C语言:掌握编程的基石
|
3月前
|
存储 Java 程序员
【C语言入门】C语言入门:探索编程世界的基础概念
【C语言入门】C语言入门:探索编程世界的基础概念
74 2
|
3月前
|
前端开发 C语言 C++
C语言入门02---环境搭建
C语言入门02---环境搭建