0%

C语言实现一个简单的通讯录程序

一个合格的通讯录,应该支持增、删、查、改这四个基本操作,同时,我在这个通讯录中也运用了内存的动态管理与文件操作的知识,同时这个通讯录可以支持按照联系人姓名进行排序。

GitHub链接

头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct PersonalInfo
{//单个联系人的信息
char name[1024];
char sex[20];
char age[10];
char phone[1024];
char address[1024];
}PersonalInfo;

typedef struct AddressBook
{//通讯录
PersonalInfo* persons;
int size;//通讯录当前的大小
int nums;//通讯录的上限
}AddressBook;

AddressBook address_book;

void Init(AddressBook* addr);//初始化
void Relloc_Per(AddressBook* addr);//扩容

int menu();//菜单

void Add_Person_Info(AddressBook* addr);//增加联系人
void Del_Person_Info(AddressBook* addr);//删除联系人
void Find_Person_Info(AddressBook* addr);//查找联系人
void Modify_Person_Info(AddressBook* addr);//修改联系人
void Print_Person_Info(AddressBook* addr);//打印通讯录
void Clear_Person_Info(AddressBook* addr);//清空通讯录

通讯录main函数部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include"AddressBook.h"

void Open(AddressBook* addr)//从本地中打开通讯录
{
FILE* addbook = fopen("C:book.txt", "r");
if (addbook == NULL)
{
perror("文件打开失败!");
return;
}
PersonalInfo buf = { 0 };
while (fread(&buf, sizeof(PersonalInfo), 1, addbook))
{
addr->persons[addr->size] = buf;
addr->size++;
if (addr->size >= addr->nums)
{
Relloc_Per(addr);
}
}
fclose(addbook);
return;
}

void Close(AddressBook* addr)//关闭程序时保存通讯录
{
FILE* addbook = fopen("C:book.txt", "w");
if (addbook == NULL)
{
perror("文件打开失败!");
return;
}
for (int i = 0; i < addr->size; i++)
{
fwrite((addr->persons + i), sizeof(PersonalInfo), 1, addbook);
}
fclose(addbook);
return;
}

int main()
{
Init(&address_book);//初始化通讯录
Open(&address_book);//打开本地文件
typedef void(*Func)(AddressBook*);//函数指针
Func function[] = //函数指针数组
{
NULL,//此处为了和menu的返回值匹配,将function[0]的内容写成NULL
Add_Person_Info,
Del_Person_Info,
Find_Person_Info,
Modify_Person_Info,
Print_Person_Info,
Clear_Person_Info
};
while (1)
{
int choice = menu();
if (choice == 0)
{//退出
Close(&address_book);
printf("bye!\n\n");
break;
}
if (choice < 0 || choice >= sizeof(function) / sizeof(function[0]))
{
printf("输入错误!\n\n");
continue;
}
function[choice](&address_book);//实现具体功能

}
return 0;
}

功能函数部分

初始化以及菜单函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void Init(AddressBook* addr)//初始化通讯录
{
addr->size = 0;
addr->nums = 20;
addr->persons = (PersonalInfo*)malloc((addr->nums) * sizeof(PersonalInfo));
for (int i = 0; i < addr->nums; i++)
{
strcpy(addr->persons[i].name , "");
strcpy(addr->persons[i].phone , "");
strcpy(addr->persons[i].address , "");
strcpy(addr->persons[i].sex , "");
strcpy(addr->persons[i].age, "");
}
}

int menu()//主菜单
{
printf("============================\n");
printf(" 1.新建联系人\n");
printf(" 2.删除联系人\n");
printf(" 3.查询联系人\n");
printf(" 4.修改联系人\n");
printf(" 5.显示所有联系人\n");
printf(" 6.清空通讯录\n");
printf(" 0.退出\n");
printf("============================\n\n");

int ret = 0;
scanf("%d", &ret);
return ret;
}

排序以及扩容部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static void cmp(AddressBook* addr) //排序
{
int i = 0;
int j = 0;
PersonalInfo tmp;
for (i = 0; i < addr->size - 1; i++)
{
for (j = 0; j < addr->size - 1 - i; j++)
{
if (strcmp(addr->persons[j].name , addr->persons[j+1].name) > 0)
{//冒泡排序
tmp = addr->persons[j];
addr->persons[j] = addr->persons[j + 1];
addr->persons[j + 1] = tmp;
}
}
}
}

void Relloc_Per(AddressBook* addr)
{
addr->nums += 20;
addr->persons = realloc(addr->persons, (addr->nums) * sizeof(PersonalInfo));
}

增删查改联系人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
void Add_Person_Info(AddressBook* addr)//新增联系人
{
if (addr->size >= addr->nums)
{
Relloc_Per(addr);
}

PersonalInfo* info = &addr->persons[addr->size];
printf("新增联系人!\n");

printf("请输入联系人姓名:");
scanf("%s", info->name);
printf("请输入联系人电话:");
scanf("%s", info->phone);
printf("请输入联系人性别:");
scanf("%s", info->sex);
printf("请输入联系人年龄:");
scanf("%s", info->age);
printf("请输入联系人住址:");
scanf("%s", info->address);

addr->size++;

printf("新增联系人成功!\n");

if (addr->size >= 2)
{
cmp(addr);
}
}

void Del_Person_Info(AddressBook* addr)//删除联系人
{
if (addr->size <= 0)
{
printf("通讯录为空!无法执行删除!\n");
return;
}
printf("删除联系人!\n");
printf("请输入要删除的联系人序号:");
int input = 0;
scanf("%d", &input);
if (input < 0 || input >= addr->size)
{
printf("非法输入!\n");
return;
}
PersonalInfo* last_info = &addr->persons[addr->size - 1];
PersonalInfo* to_delt = &addr->persons[input];
*to_delt = *last_info;
addr->size--;

printf("联系人成功删除!\n");

if (addr->size >= 2)
{
cmp(addr);
}
}

void Find_Person_Info(AddressBook* addr)//查找联系人
{
char find[1024] = { 0 };
printf("查找联系人!\n");
printf("请输入想要查找的姓名或联系方式:");
scanf("%s", &find);

for (int i = 0; i < addr->size; i++)
{
PersonalInfo* findinfo = &addr->persons[i];
if (strcmp(find, findinfo->name) == 0)
{
printf("找到了!该联系人编号为:%d\n", i);
return;
}
if (strcmp(find, findinfo->phone) == 0)
{
printf("\n找到了!该联系人为:[%d] 姓名:%s 联系方式:%s\n", i,findinfo->name,findinfo->phone);
return;
}
}
printf("查无此人!\n");

}

void Modify_Person_Info(AddressBook* addr)//修改联系人信息
{
if (addr->size <= 0)
{
printf("通讯录为空!无法执行!\n");
return;
}

int i = 0;
char name[1024];
char sex[20];
char age[10];
char phone[1024];
char address[1024];
printf("修改联系人信息!\n");
printf("请输入要修改的联系人编号:");
scanf("%d", &i);
if (i<0 || i>addr->size)
{
printf("输入非法!\n");
return;
}
PersonalInfo* info = &addr->persons[i];

printf("[%d] 姓名:%s 联系方式:%s \n 性别: %s 年龄: %s\n 住址:%s\n\n", i, info->name, info->phone, info->sex, info->age, info->address);

printf("请输入要修改的姓名(输入 * 表示不进行修改):");
scanf("%s", name);
if (strcmp(name , "*") != 0)
{
strcpy(addr->persons[i].name, name);
}

printf("请输入要修改的性别(输入 * 表示不进行修改):");
scanf("%s", sex);
if (strcmp(sex, "*") != 0)
{
strcpy(addr->persons[i].sex, sex);
}

printf("请输入要修改的年龄(输入 * 表示不进行修改):");
scanf("%s", age);
if (strcmp(age, "*") != 0)
{
strcpy(addr->persons[i].age, age);
}

printf("请输入要修改的联系方式(输入 * 表示不进行修改):");
scanf("%s", phone);
if (strcmp(phone, "*") != 0)
{
strcpy(addr->persons[i].phone, phone);
}

printf("请输入要修改的地址(输入 * 表示不进行修改):");
scanf("%s", address);
if (strcmp(address, "*") != 0)
{
strcpy(addr->persons[i].address, address);
}

printf("修改成功!\n");

if (addr->size >= 2)
{
cmp(addr);
}
}

打印以及清空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void Print_Person_Info(AddressBook* addr)//输出联系人(全部)
{
printf("显示所有联系人:\n\n");
for (int i = 0; i < addr->size; i++)
{
PersonalInfo* info = &addr->persons[i];
printf("[%d] 姓名:%s 联系方式:%s \n 性别: %s 年龄: %s\n 住址:%s\n\n", i,info->name ,info->phone,info->sex,info->age,info->address );
}
printf("\n到底了...\n");
}

void Clear_Person_Info(AddressBook* addr)//一键清空
{
char clear[20] = { 0 };
printf("\n清空通讯录!\n");
printf("请确认是否清空 (Y/N)\n");
scanf("%s", clear);

if (strcmp(clear, "Y") == 0 || strcmp(clear, "y") == 0)
{
//addr->size = 0;
Init(addr);
printf("成功清空通讯录!\n");
return;
}
else
{
printf("放弃清空\n");
}

}

如此,一个简单的通讯录就可以实现啦。

-------------本文结束感谢您的阅读-------------