C语言实现完整版通讯录
今天我们完成通讯录的编程实现.
其中包含了:
添加联系人信息
删除指定联系人信息
查找指定联系人信息
修改指定联系人信息
显示所有联系人信息
清空所有联系人
以名字排序所有联系人
这几项基本功能的函数实现.
这篇博客是按照面向过程的具体的思路来完成的,所以新手很容易上手.
定义联系人和通讯录结构体
1.定义通讯录必定要定义一个以人为本的结构体用来存储电话号和姓名.
2.联系人结构体完成,就需要一个通讯录结构体来记录多个数量的联系人,为了方便我们定义一个size(用来储存已经存在的人数. [0, size) 就是有效区间)
3.创建出的数组里有 1024 个空间. 但是初始情况下, 通讯录应该是空着的. 每次新增联系人, 里面才会多出一个元素
typedef struct person{
char name [1024];
char phnumber[1024];
}person;
typedef struct addressbook{
person persons[MAX_PERSON];
int size;
}addressbook;
菜单函数
当我们完成了结构体的创建,按照思路,我们首先需要一个用户交互界面,来展示给用户.并在交互界面完成具体步骤的定义.
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");
printf("输入您的选择:\n");
int choice = 0;
scanf("%d", &choice);
return choice;
}
主体函数
1.新增联系人
定义一个函数,指向通讯录所在的结构体.
其中注意点是,千万要进行是否满了的判断,否则程序会发生不可预计的情况
void addperson(addressbook* addressbook) {
int Size = addressbook->size;//传来了size的数字大小
person* p = &addressbook->persons[Size];//指针传来了
if (Size >= MAX_PERSON) {
printf("通讯录已经满了, 新增失败!\n");
return 0;
}
printf("输入新增联系人\n");
printf("请输入新联系人的姓名: ");
scanf("%s", p->name);
printf("请输入新联系人的电话: ");
scanf("%s", p->phnumber);
printf("新增联系人成功!\n");
addressbook->size++;
}
这个函数实现了让用户输入新的联系人的电话和姓名.
创建好一个专门的变量把要修改的 person 结构体变量给保存好.
此处不能直接使用结构体变量 person .p 这种形式, 必须使用结构体指针.
因为:我们是希望修改全局变量中的person 结构体.
而使用结构体变量的话, 相当于创建了一个局部变量的结构体.
此时的修改只是针对该局部变量生效, 随着函数结束, 局部变量就被释放了.
2.删除联系人
为了方便管理,我们利用数组下标来进行人数的操作;
删除联系人分为两点:
第一种:
若需要删除的联系人在最后一位,可以直接在总人数上-1进行删除(size–)
第二种:
如果 id 对应的元素是中间元素, 把最后一个元素给放在需要删除元素这里
再删除最后一个元素.
void delperson(addressbook* addressbook) {
printf("删除联系人\n");
printf("请输入要删除的联系人的编号: ");
int id = 0;
scanf("%d", &id);
if (id < 0 || id >= addressbook->size) {
printf("您输入的编号有误!\n");
return 0;
}
if (id == addressbook->size - 1) {
addressbook->size--;
printf("删除成功!\n");
return 0;
}
// 如果 id 对应的元素是中间元素, 把最后一个元素给bia过来
addressbook->persons[id]
= addressbook->persons[addressbook->size - 1];
addressbook->size--;
printf("删除成功!\n");
}
3.查找联系人
根据姓名查找:
void findPerson(addressbook* addressbook) {
printf("请输入要查找的姓名: ");
char name[1024] = {
0 };
scanf("%s", &name);
for (int i = 0; i < addressbook->size; i++) {
person* p = &addressbook->persons[i];
if (strcmp(name, p->name) == 0) {
//字符串比较函数 ==0取1
printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
}
printf("不存在这个联系人!\n");
}
printf("查找联系人完成!\n");
}
4.修改联系人
先要判断这个人编号是否存在,然后依次修改姓名,电话号
void updateperson(addressbook* addressbook) {
printf("请输入你要修改人的编号");
int num = 0;
scanf("%d", &num);
if (num > addressbook->size){
printf("联系人不存在!");
}
person*p = &addressbook->persons[num];
printf("输入要改成的姓名:\n");
char name[1024] = {
0 };
scanf("%s", &name);
strcpy(p->name, name);
printf("输入要改成的电话号:\n");
char number[1024] = {
0 };
scanf("%s", &number);
strcpy(p->phnumber, number);
printf("修改完成!\n");
}
5.显示所有联系人
循环打印persons的全部内容
void printPerson(addressbook* addressbook) {
printf("打印所有联系人\n");
for (int i = 0; i < addressbook->size; i++) {
person* p = &addressbook->persons[i];
printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
}
printf("共计 [%d] 条记录\n", addressbook->size);
}
6.清空所有联系人
依据删除最后一位的思路,循环删除
void clearperson(addressbook* addressbook) {
int num = addressbook->size;
for (int i = 0; i < num; i++){
addressbook->size--;
}
printf("清空联系人完成!\n");
}
7.联系人排序
这个排序采用了简单地冒泡排序完成,方便理解(按照字典序)
char sortperson(addressbook* addressbook){
int i = 0;
int j = 0;
for (i = 0; i < addressbook->size - 1; i++)
{
for (j = 0; j<addressbook->size - 1 - i; j++)
{
if (strcmp(addressbook->persons[j].name, (addressbook->persons[j + 1]).name)>0)
{
person tmp = addressbook->persons[j];
addressbook->persons[j] = addressbook->persons[j + 1];
addressbook->persons[j + 1] = tmp;
}
}
}
}
8.初始化函数
针对整个通讯录进行初始化.
只要把 size 设成 0 即可.
void init(addressbook* addressbook){
addressbook->size = 0;
}
typedef void(*Func)(addressbook*);
addressbook addressBook;
主函数
在主函数中插入了一个转移表
相比于用if-else语句更加方便,如果你没有学过转移表,可以自己写成if-else格式.
int main(){
Func funcs[] = {
NULL,
addperson,
delperson,
findPerson,
updateperson,
printPerson,
clearperson,
sortperson
};
while (1){
int choice = menu();
if (choice == 0){
printf("再见!\n");
break;
}
funcs[choice](&addressBook);
}
system("pause");
return 0;
}
头文件及宏定义
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define MAX_PERSON 1024
源代码
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define MAX_PERSON 1024
typedef struct person{
char name [1024];
char phnumber[1024];
}person;
typedef struct addressbook{
person persons[MAX_PERSON];
int size;
}addressbook;
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");
printf("输入您的选择:\n");
int choice = 0;
scanf("%d", &choice);
return choice;
}
void addperson(addressbook* addressbook) {
int Size = addressbook->size;//传来了size的数字大小
person* p = &addressbook->persons[Size];//指针传来了
if (Size >= MAX_PERSON) {
printf("通讯录已经满了, 新增失败!\n");
return 0;
}
printf("输入新增联系人\n");
printf("请输入新联系人的姓名: ");
scanf("%s", p->name);
printf("请输入新联系人的电话: ");
scanf("%s", p->phnumber);
printf("新增联系人成功!\n");
addressbook->size++;
}
void delperson(addressbook* addressbook) {
printf("删除联系人\n");
printf("请输入要删除的联系人的编号: ");
int id = 0;
scanf("%d", &id);
if (id < 0 || id >= addressbook->size) {
printf("您输入的编号有误!\n");
return 0;
}
if (id == addressbook->size - 1) {
addressbook->size--;
printf("删除成功!\n");
return 0;
}
// 如果 id 对应的元素是中间元素, 把最后一个元素给bia过来
addressbook->persons[id]
= addressbook->persons[addressbook->size - 1];
addressbook->size--;
printf("删除成功!\n");
}
void findPerson(addressbook* addressbook) {
printf("请输入要查找的姓名: ");
char name[1024] = {
0 };
scanf("%s", &name);
for (int i = 0; i < addressbook->size; i++) {
person* p = &addressbook->persons[i];
if (strcmp(name, p->name) == 0) {
//字符串比较函数 ==0取1
printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
}
printf("不存在这个联系人!\n");
}
printf("查找联系人完成!\n");
}
void printPerson(addressbook* addressbook) {
printf("打印所有联系人\n");
for (int i = 0; i < addressbook->size; i++) {
person* p = &addressbook->persons[i];
printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
}
printf("共计 [%d] 条记录\n", addressbook->size);
}
void updateperson(addressbook* addressbook) {
printf("请输入你要修改人的编号");
int num = 0;
scanf("%d", &num);
if (num > addressbook->size){
printf("联系人不存在!");
}
person*p = &addressbook->persons[num];
printf("输入要改成的姓名:\n");
char name[1024] = {
0 };
scanf("%s", &name);
strcpy(p->name, name);
printf("输入要改成的电话号:\n");
char number[1024] = {
0 };
scanf("%s", &number);
strcpy(p->phnumber, number);
printf("修改完成!\n");
}
void clearperson(addressbook* addressbook) {
int num = addressbook->size;
for (int i = 0; i < num; i++){
addressbook->size--;
}
printf("清空联系人完成!\n");
}
char sortperson(addressbook* addressbook){
int i = 0;
int j = 0;
for (i = 0; i < addressbook->size - 1; i++)
{
for (j = 0; j<addressbook->size - 1 - i; j++)
{
if (strcmp(addressbook->persons[j].name, (addressbook->persons[j + 1]).name)>0)
{
person tmp = addressbook->persons[j];
addressbook->persons[j] = addressbook->persons[j + 1];
addressbook->persons[j + 1] = tmp;
}
}
}
}
void init(addressbook* addressbook){
addressbook->size = 0;
}
typedef void(*Func)(addressbook*);
addressbook addressBook;
int main(){
Func funcs[] = {
NULL,
addperson,
delperson,
findPerson,
updateperson,
printPerson,
clearperson,
sortperson
};
while (1){
int choice = menu();
if (choice == 0){
printf("再见!\n");
break;
}
funcs[choice](&addressBook);
}
system("pause");
return 0;
}