目录
1.内容介绍;
实现一个类似于手机通讯录的功能,可以输入每个联系人的姓名、年龄、性别、电话、地址;每输入一个联系人就显示出整个通讯录,可以根据联系人的各个内容进行排序,通讯录的大小是可变的;
2.实现;
进入主函数,进入测试函数;
代码:
int main()
{
test();
return 0;
}
进入通讯录函数,建立一个联系人结构体变量,里面有所需要的变量,再建立一个通讯录结构体变量,里面有联系人指针(因为要求通讯录大小可变,所以不用定义数组),还有联系人个数,通讯录容量;这些都建立好后,建立一个通讯录指针,把他初始化,给data先开辟3*data大小的内存,sz=0,cap=3;进入dowhile循环,出现菜单,根据input输入结果选择case语句;如果input不为0,可以持续输入,直到可以进入case语句,为0就直接退出;
test():
void test()
{
int input = 0;
tongxunlu zhang;
chushihua(&zhang);
do
{
menu();
printf("请输入:> ");
scanf("%d", &input);
switch (input)
{
case add:
checkcapactiy(&zhang);
addcontract(&zhang);
showcontract(&zhang);
break;
case dele:
delecontract(&zhang);
showcontract(&zhang);
break;
case mod:
modcontract(&zhang);
showcontract(&zhang);
break;
case sort:
sortcontract(&zhang);
showcontract(&zhang);
break;
case show:
showcontract(&zhang);
break;
case Exit:
shifang(&zhang);
printf("退出通讯录\n");
break;
default:
printf("输入错误,重新输入\n");
break;
}
} while (input);
}
menu():
void menu()
{
printf("******************************\n");
printf("*****1.add 2.dele*****\n");
printf("*****3.mod 4.sort*****\n");
printf("*****5.show 0.exit*****\n");
printf("******************************\n");
}
chishihua():
void chushihua(tongxunlu* zhang)
{
zhang->data = (contract*)malloc(max_cap * sizeof(contract));
if (zhang->data == NULL)
{
perror("malloc");
return;
}
zhang->sz = 0;
zhang->capiticy = max_cap;
}
进入case1语句,即添加联系人,但是在添加联系人之前要检查sz和cap的大小关系,否则会内存不够;如果sz==cap,我们这里设置一次添加两个联系人大小的内存;检查完后,开始添加;add添加联系人函数是通过data这个地址加减来实现不同联系人的输入,添加完一个联系人后,sz++;然后进入show函数,这里为了美观,先打印一行目录,再使用for循环,把sz个联系人信息打印出来;
checkcapactiy():
int checkcapactiy(tongxunlu* zhang)
{
if (zhang->sz == zhang->capiticy)
{
contract* data1=(contract*)realloc(zhang->data, (zhang->capiticy + er) * sizeof(contract));
if (NULL == data1)
{
perror("checkcapactiy");
printf("增容失败\n");
return 0;
}
zhang->capiticy += er;
zhang->data = data1;
printf("增容成功\n");
return 1;
}
}
addcontract():
void addcontract(tongxunlu* zhang)
{
int a=checkcapactiy(zhang);
if (0==a)
{
return;
}
printf("请输入姓名:> ");
scanf("%s", zhang->data[zhang->sz].name);
printf("请输入年龄:> ");
scanf("%d", &(zhang->data[zhang->sz].age));
printf("请输入性别:> ");
scanf("%s", zhang->data[zhang->sz].sex);
printf("请输入电话:> ");
scanf("%s", zhang->data[zhang->sz].tele);
printf("请输入地址:> ");
scanf("%s", zhang->data[zhang->sz].addr);
zhang->sz++;
printf("添加成功\n");
}
showcontract():
void showcontract(tongxunlu* zhang)
{
int i = 0;
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "name", "age", "sex", "tele", "addr");
for (i = 0;i < zhang->sz;i++)
{
printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\n", zhang->data[i].name, zhang->data[i].age, zhang->data[i].sex, zhang->data[i].tele, zhang->data[i].addr);
}
}
进入case2,删除联系人,输入所要删除的名字,进入查找函数,通过函数返回值,来修改所对应位置的内容,把这个位置往后的元素都赋给前一位;查找函数就是接收通讯录指针和所要查找的名字,通过遍历找出那个要修改的名字的变量下标,然后返回;如果没找到,返回一个负数;
delecontract():
void delecontract(tongxunlu* zhang)
{
char name[max_name];
printf("请输入姓名:> ");
scanf("%s", name);
int ret = findcontract(zhang,name);
if (ret < 0)
{
return;
}
int i = 0;
for (i = ret;i < zhang->sz;i++)
{
zhang->data[i] = zhang->data[i + 1];
}
printf("删除成功\n");
zhang->sz--;
}
findcontract():
int findcontract(tongxunlu* zhang,char* name)
{
if (0 == zhang->sz)
{
return -1;
}
int i = 0;
for (i = 0;i < zhang->sz;i++)
{
while (0 == strcmp(zhang->data[i].name, name))
{
return i;
}
}
printf("通讯录里查无此人\n");
return -1;
}
进入case3,修改内容,输入所要修改的联系人名称,通过查找函数找到下标,重新输入下标所指向联系人的内容;
modcontract():
void modcontract(tongxunlu* zhang)
{
char name[max_name];
printf("请输入修改人姓名:> ");
scanf("%s", name);
int ret = findcontract(zhang, name);
if (ret < 0)
{
return;
}
printf("开始修改:\n");
printf("请输入姓名:> ");
scanf("%s", zhang->data[ret].name);
printf("请输入年龄:> ");
scanf("%d", &(zhang->data[ret].age));
printf("请输入性别:> ");
scanf("%s", zhang->data[ret].sex);
printf("请输入电话:> ");
scanf("%s", zhang->data[ret].tele);
printf("请输入地址:> ");
scanf("%s", zhang->data[ret].addr);
printf("修改成功\n");
}
case4是排序函数;这里是主要是使用qsort;进入sort函数,出现新的菜单栏,根据需要选择;如果是比年龄,比较函数用compare2,其他的用compare1;
sortcontract():
void sortcontract(tongxunlu* zhang)
{
static int input = 0;
menu1();
printf("请输入排序方式:> ");
scanf("%d", &input);
switch (input)
{
case 1:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 2:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare2);
break;
case 3:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 4:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 5:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
default:
break;
}
printf("排序完成\n");
}
compare1():
int compare1(const void* a, const void* b)
{
return strcmp((char*)a, (char*)b);
}
compare2():
int compare2(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
case5是显示函数;case6是释放函数,释放动态内存变量,并将其置为空指针;
shifang():
void shifang(tongxunlu* zhang)
{
free(zhang->data);
zhang->data= NULL;
}
3.完整代码:
这个通讯录是使用分文件形式写的,所以将枚举常量、函数、常量都定义在头文件里;
contract.h
#pragma once
#define max_name 20
#define max_sex 10
#define max_tele 15
#define max_addr 20
#define max_data 100
#define max_cap 3
#define er 2
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct sir
{
char name[max_name];
int age;
char sex[max_sex];
char tele[max_tele];
char addr[max_addr];
}contract;
enum choice
{
Exit,
add,
dele,
mod,
sort,
show
};
//typedef struct abc
//{
// contract data[max_data];
// int sz;
//}tongxunlu;
typedef struct abc
{
contract* data;
int sz;
int capiticy;
}tongxunlu;
void addcontract(tongxunlu*);
void showcontract(tongxunlu*);
void delecontract(tongxunlu*);
void modcontract(tongxunlu*);
void sortcontract(tongxunlu*);
int compare1(const void*, const void*);
int compare2(const void*, const void*);
int checkcapactiy(tongxunlu*);
void chushihua(tongxunlu*);
void shifang(tongxunlu*);
源2.c(定义函数):
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include"cotract.h"
void chushihua(tongxunlu* zhang)
{
zhang->data = (contract*)malloc(max_cap * sizeof(contract));
if (zhang->data == NULL)
{
perror("malloc");
return;
}
zhang->sz = 0;
zhang->capiticy = max_cap;
}
int checkcapactiy(tongxunlu* zhang)
{
if (zhang->sz == zhang->capiticy)
{
contract* data1=(contract*)realloc(zhang->data, (zhang->capiticy + er) * sizeof(contract));
if (NULL == data1)
{
perror("checkcapactiy");
printf("增容失败\n");
return 0;
}
zhang->capiticy += er;
zhang->data = data1;
printf("增容成功\n");
return 1;
}
}
//静态
//void addcontract(tongxunlu* zhang)
//{
// printf("请输入姓名:> ");
// scanf("%s", zhang->data[zhang->sz].name);
// printf("请输入年龄:> ");
// scanf("%d", &(zhang->data[zhang->sz].age));
// printf("请输入性别:> ");
// scanf("%s", zhang->data[zhang->sz].sex);
// printf("请输入电话:> ");
// scanf("%s", zhang->data[zhang->sz].tele);
// printf("请输入地址:> ");
// scanf("%s", zhang->data[zhang->sz].addr);
// zhang->sz++;
// printf("添加成功\n");
//}
void addcontract(tongxunlu* zhang)
{
int a=checkcapactiy(zhang);
if (0==a)
{
return;
}
printf("请输入姓名:> ");
scanf("%s", zhang->data[zhang->sz].name);
printf("请输入年龄:> ");
scanf("%d", &(zhang->data[zhang->sz].age));
printf("请输入性别:> ");
scanf("%s", zhang->data[zhang->sz].sex);
printf("请输入电话:> ");
scanf("%s", zhang->data[zhang->sz].tele);
printf("请输入地址:> ");
scanf("%s", zhang->data[zhang->sz].addr);
zhang->sz++;
printf("添加成功\n");
}
void showcontract(tongxunlu* zhang)
{
int i = 0;
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "name", "age", "sex", "tele", "addr");
for (i = 0;i < zhang->sz;i++)
{
printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\n", zhang->data[i].name, zhang->data[i].age, zhang->data[i].sex, zhang->data[i].tele, zhang->data[i].addr);
}
}
void delecontract(tongxunlu* zhang)
{
char name[max_name];
printf("请输入姓名:> ");
scanf("%s", name);
int ret = findcontract(zhang,name);
if (ret < 0)
{
return;
}
int i = 0;
for (i = ret;i < zhang->sz;i++)
{
zhang->data[i] = zhang->data[i + 1];
}
printf("删除成功\n");
zhang->sz--;
}
int findcontract(tongxunlu* zhang,char* name)
{
if (0 == zhang->sz)
{
return -1;
}
int i = 0;
for (i = 0;i < zhang->sz;i++)
{
while (0 == strcmp(zhang->data[i].name, name))
{
return i;
}
}
printf("通讯录里查无此人\n");
return -1;
}
void modcontract(tongxunlu* zhang)
{
char name[max_name];
printf("请输入修改人姓名:> ");
scanf("%s", name);
int ret = findcontract(zhang, name);
if (ret < 0)
{
return;
}
printf("开始修改:\n");
printf("请输入姓名:> ");
scanf("%s", zhang->data[ret].name);
printf("请输入年龄:> ");
scanf("%d", &(zhang->data[ret].age));
printf("请输入性别:> ");
scanf("%s", zhang->data[ret].sex);
printf("请输入电话:> ");
scanf("%s", zhang->data[ret].tele);
printf("请输入地址:> ");
scanf("%s", zhang->data[ret].addr);
printf("修改成功\n");
}
void menu1()
{
printf("******1.BY name******\n");
printf("******2.BY age ******\n");
printf("******3.BY sex ******\n");
printf("******4.BY tele******\n");
printf("******5.BY addr******\n");
}
void sortcontract(tongxunlu* zhang)
{
static int input = 0;
menu1();
printf("请输入排序方式:> ");
scanf("%d", &input);
switch (input)
{
case 1:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 2:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare2);
break;
case 3:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 4:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
case 5:
qsort(zhang->data, zhang->sz, sizeof(zhang->data[0]), compare1);
break;
default:
break;
}
printf("排序完成\n");
}
int compare1(const void* a, const void* b)
{
return strcmp((char*)a, (char*)b);
}
int compare2(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
void shifang(tongxunlu* zhang)
{
free(zhang->data);
zhang->data= NULL;
}
源.c(函数调用):
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include "cotract.h"
void menu()
{
printf("******************************\n");
printf("*****1.add 2.dele*****\n");
printf("*****3.mod 4.sort*****\n");
printf("*****5.show 0.exit*****\n");
printf("******************************\n");
}
void test()
{
int input = 0;
tongxunlu zhang;
chushihua(&zhang);
do
{
menu();
printf("请输入:> ");
scanf("%d", &input);
switch (input)
{
case add:
checkcapactiy(&zhang);
addcontract(&zhang);
showcontract(&zhang);
break;
case dele:
delecontract(&zhang);
showcontract(&zhang);
break;
case mod:
modcontract(&zhang);
showcontract(&zhang);
break;
case sort:
sortcontract(&zhang);
showcontract(&zhang);
break;
case show:
showcontract(&zhang);
break;
case Exit:
shifang(&zhang);
printf("退出通讯录\n");
break;
default:
printf("输入错误,重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}