目录
1.分析
1.1test.c
1>meun()打印菜单
2>枚举
3>创建、初始化通讯录
4>通过do-while循环选择
1.2contact.c
实现函数
1.3contact.h
1>头文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
2>#define 定义标识符
#define MAX 100
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 30
通过#define 定义标识符,进行更改时,只用该一处,避免了多次更改
3>结构体
表示一个人的信息
struct PeoInfo
{
char name[MAX_name];
char sex[MAX_sex];
char tele[MAX_tele];
int age;
char addr[MAX_addr];
};
通讯录
struct contact
{
struct PeoInfo data[MAX];
int sz;
};
4>函数
2.函数
2.1初始化通讯录
2.1.1分析
1>用assert断言pc
2>sz和struct PeoInfo初始化
3>下面是 memset() 函数的声明。
void *memset(void *str, int c, size_t n);
复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
参数
- str -- 指向要填充的内存块。
- c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
- n -- 要被设置为该值的字符数。
2.1.2代码
//初始化通讯录
void Initcontact(struct contact* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->data, 0, MAX*sizeof(struct PeoInfo));
}
2.2增加一个人的信息到通讯录
2.2.1分析
1>用assert断言pc
2>如果sz等于MAX,则说明通信录已满,直接返回,未满,继续
3>通过scanf输入联系人信息
注:字符串名本身就是地址,不用加&,变量前要加&
2.2.2代码
//增加一个人的信息到通讯录
void Addcontact(struct contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满!\n");
return;
}
//增加人的信息
printf("请输入名字>>");
scanf("%s", pc->data[pc->sz].name); //字符串变量名就是首地址,是地址
printf("请输入性别>>");
scanf("%s", pc->data[pc->sz].sex); //字符串变量名就是首地址,是地址
printf("请输入电话>>");
scanf("%s", pc->data[pc->sz].tele); //字符串变量名就是首地址,是地址
printf("请输入年龄>>");
scanf("%d", &(pc->data[pc->sz].age)); //是变量
printf("请输入地址>>");
scanf("%s", pc->data[pc->sz].addr); //字符串变量名就是首地址,是地址
pc->sz++;
printf("增加联系人成功\n");
}
2.3显示通讯录信息
2.3.1分析
%s以字符串的格式输出
%20s以字符串的格式输出,位宽为20
%-20s以字符串的格式输出,位宽为20,左对齐
2.3.2代码
//显示通讯录信息
void Showcontact(const struct contact* pc)
{
int i = 0;
printf("%-20s\t%-5s\t%-12s\t%-5s\t%-30s\n", "姓名","性别","电话","年龄","地址"); //c左对齐
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-12s\t%-5d\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].tele, pc->data[i].age, pc->data[i].addr);
}
}
2.4删除指定联系人的信息
2.4.1分析
1>输入要删除的人的名字
2>查找指定人是否存在,若不存在返回-1,若存在返回下标
3>把后一个的信息赋给前一个
2.4.2代码
//删除指定联系人的信息
int FindByName(const struct contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->data[i].name ,name))
return i;
}
return -1;
}
void Delcontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要删除人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret=FindByName(pc, name);
if (ret == -1)
{
printf("要删除的人不存在\n");
return;
}
//删除
int j = 0;
for (j = 0; j < pc->sz-1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->sz--;
printf("成功删除联系人\n");
}
2.5查找指定联系人的信息
2.5.1分析
1>输入要查找的人的名字
2>查找指定人是否存在,若不存在返回-1,若存在返回下标
3>输出查找人的信息
2.5.2代码
//查找指定联系人的信息
void Searchcontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要查找人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("要查找的人不存在\n");
return;
}
//查找
printf("%-20s\t%-5s\t%-12s\t%-5s\t%-30s\n", "姓名", "性别", "电话", "年龄", "地址"); //c左对齐
printf("%-20s\t%-5s\t%-12s\t%-5d\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].age, pc->data[ret].addr);
}
2.6修改指定联系人的信息
2.6.1分析
1>输入要修改的人的名字
2>查找指定人是否存在,若不存在返回-1,若存在返回下标
3>重新输入修改人的信息
2.6.2代码
//修改指定联系人的信息
void Modifycontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要修改人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("要修改的人不存在\n");
return;
}
//修改人的信息
printf("请输入名字>>");
scanf("%s", pc->data[pc->sz].name); //字符串变量名就是首地址,是地址
printf("请输入性别>>");
scanf("%s", pc->data[pc->sz].sex); //字符串变量名就是首地址,是地址
printf("请输入电话>>");
scanf("%s", pc->data[pc->sz].tele); //字符串变量名就是首地址,是地址
printf("请输入年龄>>");
scanf("%d", &(pc->data[pc->sz].age)); //是变量
printf("请输入地址>>");
scanf("%s", pc->data[pc->sz].addr); //字符串变量名就是首地址,是地址
pc->sz++;
printf("增加联系人成功\n");
}
2.7排序
1>下面是 qsort() 函数的声明。
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
对数组进行排序。
2>参数
- base -- 指向要排序的数组的第一个元素的指针。
- nitems -- 由 base 指向的数组中元素的个数。
- size -- 数组中每个元素的大小,以字节为单位。
- compar -- 用来比较两个元素的函数。
3>返回值
该函数不返回任何值。
2.7.1分析
按名字排
下面是 strcmp() 函数的声明。
int strcmp(const char *str1, const char *str2)
把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
参数
- str1 -- 要进行比较的第一个字符串。
- str2 -- 要进行比较的第二个字符串。
返回值
该函数返回值如下:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
2.7.2代码
void Sortcontact(struct contact* pc)
{
-按年龄排
//qsort( pc->data, pc->sz, sizeof(struct PeoInfo), CmpByAge);
//-按名字排
qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByName);
}
1>按年龄排
//-按年龄排
void CmpByAge(const void* e1, const void* e2)
{
return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
2>按名字排
//-按名字排
void CmpByName(const void* e1, const void* e2)
{
return strcmp(((struct PeoInfo*)e1)->name ,((struct PeoInfo*)e2)->name);
}
3.代码
3.1test.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
void meun()
{
printf("********************************\n");
printf("****1.add 2.del ***\n");
printf("****3.search 4.modify ***\n");
printf("****5.show 6.sort ***\n");
printf("****0.exit ****************\n");
printf("********************************\n");
}
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
int main()
{
int input = 0;
//创建通讯录
struct contact con;
//初始化通讯录
Initcontact(&con);
//n个信息,再增加一个放到下标为n的位置上
do {
meun();
printf("请选择>>\n");
scanf("%d", &input);
switch (input)
{
case ADD:
Addcontact(&con);
break;
case DEL:
Delcontact(&con);
break;
case SEARCH:
Searchcontact(&con);
break;
case MODIFY:
Modifycontact(&con);
break;
case SHOW:
Showcontact(&con);
break;
case SORT:
Sortcontact(&con);
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("输入错误\n");
break;
}
}
} while (input);
return 0;
}
3.2contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
//初始化通讯录
void Initcontact(struct contact* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->data, 0, MAX*sizeof(struct PeoInfo));
}
//增加一个人的信息到通讯录
void Addcontact(struct contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满!\n");
return;
}
//增加人的信息
printf("请输入名字>>");
scanf("%s", pc->data[pc->sz].name); //字符串变量名就是首地址,是地址
printf("请输入性别>>");
scanf("%s", pc->data[pc->sz].sex); //字符串变量名就是首地址,是地址
printf("请输入电话>>");
scanf("%s", pc->data[pc->sz].tele); //字符串变量名就是首地址,是地址
printf("请输入年龄>>");
scanf("%d", &(pc->data[pc->sz].age)); //是变量
printf("请输入地址>>");
scanf("%s", pc->data[pc->sz].addr); //字符串变量名就是首地址,是地址
pc->sz++;
printf("增加联系人成功\n");
}
//显示通讯录信息
void Showcontact(const struct contact* pc)
{
int i = 0;
printf("%-20s\t%-5s\t%-12s\t%-5s\t%-30s\n", "姓名","性别","电话","年龄","地址"); //c左对齐
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-12s\t%-5d\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].tele, pc->data[i].age, pc->data[i].addr);
}
}
//删除指定联系人的信息
int FindByName(const struct contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->data[i].name ,name))
return i;
}
return -1;
}
void Delcontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要删除人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret=FindByName(pc, name);
if (ret == -1)
{
printf("要删除的人不存在\n");
return;
}
//删除
int j = 0;
for (j = 0; j < pc->sz-1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->sz--;
printf("成功删除联系人\n");
}
//查找指定联系人的信息
void Searchcontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要查找人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("要查找的人不存在\n");
return;
}
//查找
printf("%-20s\t%-5s\t%-12s\t%-5s\t%-30s\n", "姓名", "性别", "电话", "年龄", "地址"); //c左对齐
printf("%-20s\t%-5s\t%-12s\t%-5d\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].age, pc->data[ret].addr);
}
//修改指定联系人的信息
void Modifycontact(struct contact* pc)
{
char name[MAX_name];
printf("请输入要修改人的名字\n");
scanf("%s", name);
//查找指定人是否存在
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("要修改的人不存在\n");
return;
}
//修改人的信息
printf("请输入名字>>");
scanf("%s", pc->data[pc->sz].name); //字符串变量名就是首地址,是地址
printf("请输入性别>>");
scanf("%s", pc->data[pc->sz].sex); //字符串变量名就是首地址,是地址
printf("请输入电话>>");
scanf("%s", pc->data[pc->sz].tele); //字符串变量名就是首地址,是地址
printf("请输入年龄>>");
scanf("%d", &(pc->data[pc->sz].age)); //是变量
printf("请输入地址>>");
scanf("%s", pc->data[pc->sz].addr); //字符串变量名就是首地址,是地址
pc->sz++;
printf("增加联系人成功\n");
}
//排序
//-按年龄排
void CmpByAge(const void* e1, const void* e2)
{
return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
//-按名字排
void CmpByName(const void* e1, const void* e2)
{
return strcmp(((struct PeoInfo*)e1)->name ,((struct PeoInfo*)e2)->name);
}
void Sortcontact(struct contact* pc)
{
-按年龄排
//qsort( pc->data, pc->sz, sizeof(struct PeoInfo), CmpByAge);
//-按名字排
qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByName);
}
3.3contact.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX 100
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 30
//表示一个人的信息
struct PeoInfo
{
char name[MAX_name]; //字符串变量名就是首地址,是地址
char sex[MAX_sex];
char tele[MAX_tele];
int age; //变量,不是地址
char addr[MAX_addr];
};
//通讯录
struct contact
{
struct PeoInfo data[MAX];
int sz;
};
//初始化通讯录
void Initcontact(struct contact* pc);
//增加一个人的信息到通讯录
void Addcontact(struct contact* pc);
//删除指定联系人的信息
void Delcontact(struct contact* pc);
//查找指定联系人的信息
void Searchcontact(struct contact* pc);
//修改指定联系人的信息
void Modifycontact(struct contact* pc);
//排序
void Sortcontact(struct contact* pc);
//显示通讯录信息
void Showcontact(const struct contact* pc);