【c语言】通讯录(静态)

简介: 【c语言】通讯录(静态)

小张刚学习完结构体,枚举,联合相关的知识,实践实践,写一个通讯录呗!


通讯录的功能

1.通讯录可存放100的信息

2.信息的内容姓名,性别,年龄,电话,地址

3.支持增加联系人

4.支持删除联系人

5.支持查找联系人

6.支持修改联系人

7.支持排序联系人

8.打印数据

文件类型

test.c(测试通讯录相关功能)

contanct.c(通讯录功能的实现)

contanct.h(声明)

一个人信息在结构体中定义

struct peoinfo {

char name[20];姓名

char sex[5];性别

int age;年龄

char tel[12];电话

char addr[20];};地址

为了方便代码的可读性,我们在宏里面定义每个字符串数组的长度,修改如下

struct peoinfo {

char name[MAX_NAME];姓名

char sex[MAX_SEX];性别

int age;年龄

char tel[MAX_TEL];电话

char addr[MAX_ADDR];地址};

宏定义如下

#define MAX_NAME 20

#define MAX_SEX 6

#define MAX_TEL 12

#define MAX_ADDR 20

#define MAX 1000

通讯录用结构体

typedef struct pp{

struct peoinfo arr[MAX];

int sz;}pp;

用typedef将通讯录结构体类型重命名为pp,方便操作

菜单函数menu

void menu()
{
  printf("#######################################\n");
  printf("#*********    1.add    ***************#\n");
  printf("#*********    2.del    ***************#\n");
  printf("#*********    3.search ***************#\n");
  printf("#*********    4.modify ***************#\n");
  printf("#*********    5.sort   ***************#\n");
  printf("#*********    6.print  ****************#\n");
  printf("##########    0.exit   ################\n");
}

选择功能函数test()

void test()
{pp pro;//定义一个通讯录
Initcontanct(&pro);//通讯录初始化,具体在下面
int input;
  do {
    menu();
    scanf_s("%d", &input);
    switch (input)
    {
    case 1:
      Addcontanct(&pro);
      break;
    case 2:
      Delcontanct(&pro);
      break;
    case 3:
      findcontanct(&pro);
      break;
    case 4:
      modifycontanct(&pro);
      break;
    case 5:
      Sortcontanct(&pro);
      break;
    case 6:
      Printcontanct(&pro);
      break;
    case 7:
      break;
    case 0:
      printf("退出通讯录\n");
      break;
    default:
      printf("输入错误,请重新输入\n");
      break;
    }
  } while (input);
}

switch语句中的case1,2,3,4不好对应功能,为了提高代码可读性,我们可以定义一个枚举类型

enum opion

{

EXIT,//他的值为0,下面依次1,2,3,4,5,6

ADD,

DEL,

SEARCH,

MODIFY,

SORT,

PRINT

};

test()函数修改

void test()
{pp pro;
Initcontanct(&pro);
int input;
  do {
    menu();
    scanf_s("%d", &input);
    switch (input)
    {
    case  ADD:
      Addcontanct(&pro);
      break;
    case DEL:
      Delcontanct(&pro);
      break;
    case SEARCH:
      findcontanct(&pro);
      break;
    case MODIFY:
      modifycontanct(&pro);
      break;
    case SORT:
      Sortcontanct(&pro);
      break;
    case PRINT:
      Printcontanct(&pro);
      break;
    case EXIT:
      printf("退出通讯录\n");
      break;
    default:
      printf("输入错误,请重新输入\n");
      break;
    }
  } while (input);
}

初始化通讯录函数

作用:将sz初始化为0,将struct peoinfo arr[]初始化为0,防止初始化为随机值,memset函数可以将从哪个地址开始多少个字节置为你想置的数,第一个参数是从哪个地址开始重置,第二个参数是置为什么,第三个参数是置多少个字节,memset头文件stdlib.h

void Initcontanct(pp*p)
{
  p->sz = 0;
  memset(p->arr, 0, sizeof(p->arr));
}

结构体指针p接收通讯录的地址&pro

添加联系人

void Addcontanct(pp* p)
{
  if (p->sz == 1000)
  {
    printf("通讯录已经存满\n");
    return;
  }
  printf("请输入姓名\n");
  scanf("%s",p->arr[p->sz].name);
  printf("请输入性别\n");
  scanf("%s",p->arr[p->sz].sex);
  printf("请输入年龄\n");
  scanf("%d",&(p->arr[p->sz].age));
  printf("请输入电话\n");
  scanf("%s",p->arr[p->sz].tel);
  printf("请输入地址\n");
  scanf("%s",p->arr[p->sz].addr);
  p->sz++;
  printf("录入成功\n");
}

注意年龄不是数组,scanf的时候必须加&取地址符,每次添加1个,p->sz+1;如果==1000,表示已经存满,return直接跳出,不再进行添加过程

打印数据函数

void Printcontanct(pp* p)
{
  int i = 0;
  printf("******************************************************\n");
  printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址");
  printf("******************************************************\n");
  for (i = 0; i < p->sz; i++)
  {
    printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr);
    printf("******************************************************\n");
  }
}

注意:为了能打印更加美观,打印采用左对齐,打印*的每行为了将用户分开,更好看一点,循环遍历通讯录每个成员,将其打印,每个用户打印完了,记得换行

删除联系人

void Delcontanct(pp* p)
{
  char name[MAX_NAME];
  printf("请输入要删除朋友的名字\n");
  scanf("%s",name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    for (int j = k; j < p->sz - 1; j++)
    {
      p->arr[j] = p->arr[j + 1];
    }
    p->sz--;
    printf("删除成功\n");
}
}

查找函数find()

int find(pp* p, char name[])
{
  int i = 0;
  for (int i = 0; i < p->sz; i++)
  {
    if (!strcmp(p->arr[i].name, name))
      return i;
  }
  return -1;
}

注意查找函数的功能是遍历通讯录,如果有此人,返回这个人数组的下标,如果没有此人,返回-1;使用strcmp比较函数记得头文件string.h,删除一个人,输入要删除的那个人的名字,将输入名字的数组地址和通讯录的地址传给find()函数,调用find()函数遍历通讯录,如果没有此人,find()函数返回-1;打印查无此人,否则用k接收其要删除用户的下标,将k下标的用户删除,然后将后面的依次向前挪,删除一个,对应的p->sz- -

查找联系人

void findcontanct(pp* p)
{
  char name[MAX_NAME];
  if (p->sz == 0)
  {
    printf("通讯录为空\n");
    return;
  }
  printf("请输入要查找朋友的名字\n");
  scanf("%s", name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    printf("******************************************************\n");
    printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
    printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr);
    printf("******************************************************\n");
  }
}

注意:查找基本和删除类似,输入名字后,需要调用find函数查找对应名字的下标,返回-1;表示没找到,如果返回了下标将这个下标对应的信息打印出来

修改联系人信息

void modifycontanct(pp* p)
{
  char name[MAX_NAME];
  printf("请输入修改朋友的名字\n");
  scanf("%s", name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    printf("请输入要修改朋友的信息\n");
    printf("修改性别->");
    scanf("%s", p->arr[k].sex);
    printf("修改年龄->");
    scanf("%d", &(p->arr[k].age));
    printf("修改电话->");
    scanf("%s", p->arr[k].tel);
    printf("修改地址->");
    scanf("%s", p->arr[k].addr);
    printf("修改成功\n");
     }
}

注意修改联系人信息还是需要find()函数查找联系人名字,find()函数返回其下标,修改的时候,直接对下标对应的用户进行操作,年龄不是数组,scanf需要加&取地址符

排序联系人(年龄排序)

void Sortcontanct(pp* p)
{
  int i = 0;
  for (int i = 0; i < p->sz-1; i++)
  {
    for (int j = 0; j < p->sz - i-1; j++)
    {
      if (p->arr[j].age > p->arr[j + 1].age)
      {
        int tmp = p->arr[j].age;
        p->arr[j].age = p->arr[j + 1].age;
        p->arr[j + 1].age = tmp;
        char name[MAX_NAME];
        strcpy(name, p->arr[j].name);
        strcpy(p->arr[j].name, p->arr[j+1].name);
        strcpy(p->arr[j + 1].name, name);
        char sex[MAX_SEX];
        strcpy(sex, p->arr[j].sex);
        strcpy(p->arr[j].sex, p->arr[j + 1].sex);
        strcpy(p->arr[j + 1].sex, sex);
        char tel[MAX_TEL];
        strcpy(tel, p->arr[j].tel);
        strcpy(p->arr[j].tel, p->arr[j + 1].tel);
        strcpy(p->arr[j + 1].tel, tel);
        char addr[MAX_ADDR];
        strcpy(addr, p->arr[j].addr);
        strcpy(p->arr[j].addr, p->arr[j + 1].addr);
        strcpy(p->arr[j + 1].addr, tel);
             }
    }
}
  printf("按年龄排序成功,快去打印吧\n");
}

注意利用冒泡排序按年龄从小到大排序,将年龄交换的同时,需要将两个人的名字,性别,电话,住址也进行交换,字符串数组,我们采用strcpy,strcpy头文件string.h,交换的思想也是用到了三个数交换的灵感

但是我的上一篇讲的是qsort排序,我们也可以用qsort进行排序,拒绝屎山代码

修改:排序联系人

int int_cmp_age(const void* p1, const void* p2)//按年龄比较
{
  return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age;
}
void Sortcontanct(pp* p)
{
  qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age);
    printf("按年龄排序成功,快去打印吧\n");
}

整体代码展示

contanct.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TEL 12
#define MAX_ADDR 20
#define MAX 1000
enum opion
{
  EXIT,
    ADD,
  DEL,
    SEARCH,
  MODIFY,
  SORT,
  PRINT
};
typedef struct peoinfo {
  char name[MAX_NAME];
  char sex[MAX_SEX];
  int age;
  char tel[MAX_TEL];
  char addr[MAX_ADDR];
}peoinfo;
typedef struct pp{
  struct peoinfo arr[MAX];
  int sz;
}pp;
void Initcontanct(pp*p);
void Addcontanct(pp* p);
void Printcontanct(pp* p);
void Delcontanct(pp* p);
void findcontanct(pp* p);
void modifycontanct(pp* p);
void Sortcontanct(pp* p);

contanct.c

#include"contanct.h"
void Initcontanct(pp*p)
{
  p->sz = 0;
  memset(p->arr, 0, sizeof(p->arr));
}
void Addcontanct(pp* p)
{
  if (p->sz == 1000)
  {
    printf("通讯录已经存满\n");
    return;
  }
  printf("请输入姓名\n");
  scanf("%s",p->arr[p->sz].name);
  printf("请输入性别\n");
  scanf("%s",p->arr[p->sz].sex);
  printf("请输入年龄\n");
  scanf("%d",&(p->arr[p->sz].age));
  printf("请输入电话\n");
  scanf("%s",p->arr[p->sz].tel);
  printf("请输入地址\n");
  scanf("%s",p->arr[p->sz].addr);
  p->sz++;
  printf("录入成功\n");
}
void Printcontanct(pp* p)
{
  int i = 0;
  printf("******************************************************\n");
  printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址");
  printf("******************************************************\n");
  for (i = 0; i < p->sz; i++)
  {
    printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr);
    printf("******************************************************\n");
  }
}
int find(pp* p, char name[])
{
  int i = 0;
  for (int i = 0; i < p->sz; i++)
  {
    if (!strcmp(p->arr[i].name, name))
      return i;
  }
  return -1;
}
void Delcontanct(pp* p)
{
  char name[MAX_NAME];
  printf("请输入要删除朋友的名字\n");
  scanf("%s",name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    for (int j = k; j < p->sz - 1; j++)
    {
      p->arr[j] = p->arr[j + 1];
    }
    p->sz--;
    printf("删除成功\n");
}
}
void findcontanct(pp* p)
{
  char name[MAX_NAME];
  if (p->sz == 0)
  {
    printf("通讯录为空\n");
    return;
  }
  printf("请输入要查找朋友的名字\n");
  scanf("%s", name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    printf("******************************************************\n");
    printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
    printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr);
    printf("******************************************************\n");
  }
}
void modifycontanct(pp* p)
{
  char name[MAX_NAME];
  printf("请输入修改朋友的名字\n");
  scanf("%s", name);
  if (find(p, name) == -1)
  {
    printf("查无此人\n");
  }
  else
  {
    int k = find(p, name);
    printf("请输入要修改朋友的信息\n");
    printf("修改性别->");
    scanf("%s", p->arr[k].sex);
    printf("修改年龄->");
    scanf("%d", &(p->arr[k].age));
    printf("修改电话->");
    scanf("%s", p->arr[k].tel);
    printf("修改地址->");
    scanf("%s", p->arr[k].addr);
    printf("修改成功\n");
     }
}
int int_cmp_age(const void* p1, const void* p2)//按年龄比较
{
  return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age;
}
void Sortcontanct(pp* p)
{
  qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age);
    printf("按年龄排序成功,快去打印吧\n");
}

test.c

#include"contanct.h"
void menu()
{
  printf("#######################################\n");
  printf("#*********    1.add    ***************#\n");
  printf("#*********    2.del    ***************#\n");
  printf("#*********    3.search ***************#\n");
  printf("#*********    4.modify ***************#\n");
  printf("#*********    5.sort   ***************#\n");
  printf("#*********    6.print  ****************#\n");
  printf("##########    0.exit   ################\n");
}
void test()
{pp pro;
Initcontanct(&pro);
int input;
  do {
    menu();
    scanf_s("%d", &input);
    switch (input)
    {
    case  ADD:
      Addcontanct(&pro);
      break;
    case DEL:
      Delcontanct(&pro);
      break;
    case SEARCH:
      findcontanct(&pro);
      break;
    case MODIFY:
      modifycontanct(&pro);
      break;
    case SORT:
      Sortcontanct(&pro);
      break;
    case PRINT:
      Printcontanct(&pro);
      break;
    case EXIT:
      printf("退出通讯录\n");
      break;
    default:
      printf("输入错误,请重新输入\n");
      break;
    }
  } while (input);
}
void main()
{
  test();
}

结果展示

存在的问题大家可以指出,后面会和大家分享动态通讯录,大家多多支持,还有就是我访问终于破2000了哈哈哈哈哈

彩蛋

今天分享就到这里,下一篇见

目录
相关文章
|
C语言
C语言——通讯录系统—基于 VS2022
C语言——通讯录系统—基于 VS2022
123 0
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
173 2
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
机器学习/深度学习 搜索推荐 程序员
C语言实现个人通讯录(功能优化)-2
C语言实现个人通讯录(功能优化)
137 0
C语言实现个人通讯录(功能优化)-2
|
存储 C语言 索引
C语言实现个人通讯录(功能优化)-1
C语言实现个人通讯录(功能优化)
144 0
C语言实现个人通讯录(功能优化)-1
|
C语言
C语言学习记录——通讯录(静态内存)
C语言学习记录——通讯录(静态内存)
97 2
|
存储 C语言
C语言实现通讯录
C语言实现通讯录
105 2
|
存储 C语言
C语言实验-动态顺序表实现简易通讯录(二)
在这个C语言实验中,你将实现一个简单的通讯录,它使用动态顺序表来存储联系人信息。
156 2
|
存储 C语言
C语言实验-动态顺序表实现简易通讯录(一)
本文介绍了使用C语言模拟实现通讯录的步骤,包括使用动态顺序表存储联系人信息,每个联系人包含姓名、性别、电话和住址。功能包括新增、查找、删除、修改和查看联系人信息,以及按关键词排序。代码示例展示了如何定义联系人结构体、通讯录顺序表,以及主函数中的菜单选择和输入处理。文章还强调了在读取用户输入时避免出现死循环的问题,并提供了初始化和销毁通讯录的函数,以及如何判断和增加通讯录容量的方法。
166 1
|
C语言
c语言小课设--通讯录(动态内存管理+可持久化数据)
c语言小课设--通讯录(动态内存管理+可持久化数据)