前言:
通过c语言来模拟一个通讯录的实现,来储存1000个联系人的信息,并保存在文件中
每个个人信息包括:
姓名,性别,电话,地址
功能包括:
联系人的添加
联系人的删除
联系人的查找
联系人的修改
- 结构体的定义
typedef struct list{
char name[10];
char sex[10];
char phone[20];
char address[30];
int n;
}List;
结构体的成员皆为字符型,因为这样在我们储存通讯录的.txt文档中就可以直接查看所有的通讯录成员的内容。
- 菜单
一个通讯录的实现离不开菜单,菜单的主要作用是将各个功能联系在一起,使使用者根据自己的要求,使用通讯录。
void menu(){
int n;
do{
printf("*********************************\n");
printf("** 1. 添加联系人 **\n");
printf("** 2. 删除联系人 **\n");
printf("** 3. 查找联系人 **\n");
printf("** 4. 修改联系人 **\n");
printf("** 0. 退出 **\n");
printf("*********************************\n");
scanf("%d",&n);
if(n == 1){
add();
}
else if(n == 2){
del();
}
else if(n == 3){
seek();
}
else if(n == 4){
modify();
}
}while(n != 0);
}
通过输入n值进行功能的选择,用do while 结构,让使用者在进行一个功能的完整实现后,能够回到菜单进行下一个功能的选择,直到n == 0 时,退出菜单。
- 功能模块的实现
全局变量和宏定义
#define NUM 1000//用来设置最大存储量
int now = 0;//用来标识当前存储的数量
(1)添加联系人
void add(){
char cn;
do{
if(now == NUM){
printf("通讯录已满\n");
}
else{
printf("请输入姓名\n");
scanf("%s",&a[now].name);
printf("请输入性别\n");
scanf("%s",&a[now].sex);
printf("请输入电话\n");
scanf("%s",&a[now].phone);
printf("请输入地址\n");
scanf("%s",&a[now].address);
now++;
}
printf("如果你想继续添加联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
注:scanf前面要有getchar,用来读走回车符
(2)删除联系人
void del(){
char cn;
do{
printf("如果你想删除所有联系人请按1\n");
printf("如果你想删除单个联系人请按2\n");
int n;
scanf("%d",&n);
if(n == 1){
init();//自定义的初始化函数
now =0;
}
else if(n == 2){
printf("请输入要删除联系人的姓名\n");
char b[10];
int f = 0;
scanf("%s",b);
for(int i =0;i<now;i++){
if(strcmp(b,a[i].name) == 0){
f++;
memset(&a[i],0,sizeof(List));
if(i < now-1){//判断删除的联系人是否是最后一个
while(i<now-1){//将后一个联系人向前移一个,填补空缺
strcpy(a[i].name,a[i+1].name);
strcpy(a[i].sex ,a[i+1].sex);
strcpy(a[i].phone,a[i+1].phone);
strcpy(a[i].address,a[i+1].address);
memset(&a[i+1],0,sizeof(List));//将后一个联系人删掉
i++;
}
}
now--;
break;
}
}
if(f == 0){
printf("未找到该联系人\n");
}
printf("如果你想继续删除联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}
}while(cn == 'y');
}
大致流程与add函数差不多,主要是该函数有两个选项,一个为清空通讯录,一个为清除单个联系人。
同时在删除单个联系人的时候要进一步判断是否删除的是最后一个联系人,如果不是则还需要将选中要删除联系人后面的联系人往前移。
(3)查找联系人
void seek (){
char cn;
do{
printf("请输入你所要查找的内容(姓名\\性别\\电话\\地址)\n");
char b[30];
scanf("%s",b);
int i,f = 0;
char *p[4];//指针数组,每个数组元素可以看成一个指针
for(i =0;i<now;i++){
p[0] = strstr(a[i].name,b);
p[1] = strstr(a[i].sex,b);
p[2] = strstr(a[i].phone,b);
p[3] = strstr(a[i].address,b);
//strstr用来查找子集的,比如说123,你输入12,12为123的子集,就会返回一个指针
//否则返回一个空指针
if(p[0] !=NULL ||p[1] != NULL||p[2] != NULL||p[3] != NULL){
f++;
printf("第%d个\n姓名:%s\n性别:%s\n电话:%s\n地址:%s\n"
,f,a[i].name,a[i].sex,a[i].phone, a[i].address);
}
}
if(f==0){
printf("未查到相应内容\n");
}
printf("如果你想继续查找联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
该部分使用了<string.h>中的strstr函数,具体用法可以进行百度,大致是寻找元素的子集,如:一个联系人叫张三,但你不知到他姓什么,只知道有个三,你就可以通过三来寻找张三。
(4)修改联系人
void modify (){
char cn;
do{
printf("请输入要修改的联系人姓名\n");
char b[10];
int f = 0;
scanf("%s",b);
for(int i=0;i<now;i++){
if(strcmp(b,a[i].name) == 0){
f++;
printf("修改后的姓名\n");
scanf("%s",&a[i].name);
printf("修改后的性别\n");
scanf("%s",&a[i].sex);
printf("修改后的电话\n");
scanf("%s",&a[i].phone);
printf("修改后的地址\n");
scanf("%s",&a[i].address);
break;
}
}
if(f == 0){
printf("未找到该联系人");
}
printf("如果你想继续修改联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
该部分较简单,用strcmp寻找要修改的联系人的名字,然后进行修改就行。
- 文件的读取和写入
(1)文件读取
void copy(){
init();
FILE *pf;
if((pf = fopen("list.txt","r")) ==NULL){
printf("通讯录打开失败\n");
exit(1);
}
else{
int n,i=0;
do{
n = fread(&a[i++],sizeof(List),1,pf);
}while(n == 1);
now = i-1;
}
fclose(pf);
}
void init (){
memset(a,0,sizeof(List)*NUM);
}
文件的读取要放在整个程序的开头,因为程序主体部分是通过修改结构体数组中的内容实现的,并不是直接在文件中进行操作,因此要先将通讯录已有的成员读取到结构体数组中,再对结构体数组进行操作。
注:要事先再对应的文件夹中设置list.txt文件储存通讯录的内容,因为“r”是打开已有的文件。
(2)文件的写入
void file (){
FILE *f;
if( ( f = fopen("list.txt","w")) == NULL){
printf("打开失败\n");
exit(-1);
}
else{
int i = 0;
while(i<now){
fwrite(&a[i],sizeof(List),1,f);
i++;
}
}
fclose(f);
}
文件的写入放到整个程序的后面,当使用者完成所有的功能,结构体数组的内容不会再发生变化时,便可以将结构体数组写入程序,“w”打开,可以理解为更新文件,新的文件会覆盖旧的文件,以实现文件内容的修改。
- 完整代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NUM 1000 //通讯录最大容量
typedef struct list{
char name[10];
char sex[10];
char phone[20];
char address[30];
}List;
List a[NUM];//结构体数组
int now = 0;//用来标记一共有多少个联系人
void init ();
void copy();
void menu();
void add();
void seek();
void del();
void modify();
void file();
void init (){
memset(a,0,sizeof(List)*NUM);
}
void copy(){
init();
FILE *pf;
if((pf = fopen("list.txt","r")) ==NULL){
printf("通讯录打开失败\n");
exit(1);
}
else{
int n,i=0;
do{
n = fread(&a[i++],sizeof(List),1,pf);
}while(n == 1);
now = i-1;
}
fclose(pf);
}
void menu(){
int n;
do{
printf("*********************************\n");
printf("** 1. 添加联系人 **\n");
printf("** 2. 删除联系人 **\n");
printf("** 3. 查找联系人 **\n");
printf("** 4. 修改联系人 **\n");
printf("** 0. 退出 **\n");
printf("*********************************\n");
scanf("%d",&n);
if(n == 1){
add();
}
else if(n == 2){
del();
}
else if(n == 3){
seek();
}
else if(n == 4){
modify();
}
}while(n != 0);
}
void add(){
char cn;
do{
if(now == NUM){
printf("通讯录已满\n");
}
else{
printf("请输入姓名\n");
scanf("%s",&a[now].name);
printf("请输入性别\n");
scanf("%s",&a[now].sex);
printf("请输入电话\n");
scanf("%s",&a[now].phone);
printf("请输入地址\n");
scanf("%s",&a[now].address);
now++;
}
printf("如果你想继续添加联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
void del(){
char cn;
do{
printf("如果你想删除所有联系人请按1\n");
printf("如果你想删除单个联系人请按2\n");
int n;
scanf("%d",&n);
if(n == 1){
init();
now =0;
}
else if(n == 2){
printf("请输入要删除联系人的姓名\n");
char b[10];
int f = 0;
scanf("%s",b);
for(int i =0;i<now;i++){
if(strcmp(b,a[i].name) == 0){
f++;
memset(&a[i],0,sizeof(List));
if(i < now-1){//判断删除的联系人是否是最后一个
while(i<now-1){//将后一个联系人向前移一个,填补空缺
strcpy(a[i].name,a[i+1].name);
strcpy(a[i].sex ,a[i+1].sex);
strcpy(a[i].phone,a[i+1].phone);
strcpy(a[i].address,a[i+1].address);
memset(&a[i+1],0,sizeof(List));//将后一个联系人删掉
i++;
}
}
now--;
break;
}
}
if(f == 0){
printf("未找到该联系人\n");
}
printf("如果你想继续删除联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}
}while(cn == 'y');
}
void seek (){
char cn;
do{
printf("请输入你所要查找的内容(姓名\\性别\\电话\\地址)\n");
char b[30];
scanf("%s",b);
int i,f = 0;
char *p[4];//指针数组,每个数组元素可以看成一个指针
for(i =0;i<now;i++){
p[0] = strstr(a[i].name,b);
p[1] = strstr(a[i].sex,b);
p[2] = strstr(a[i].phone,b);
p[3] = strstr(a[i].address,b);
//strstr用来查找子集的,比如说123,你输入12,12为123的子集,就会返回一个指针
//否则返回一个空指针
if(p[0] !=NULL ||p[1] != NULL||p[2] != NULL||p[3] != NULL){
f++;
printf("第%d个\n姓名:%s\n性别:%s\n电话:%s\n地址:%s\n"
,f,a[i].name,a[i].sex,a[i].phone, a[i].address);
}
}
if(f==0){
printf("未查到相应内容\n");
}
printf("如果你想继续查找联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
void modify (){
char cn;
do{
printf("请输入要修改的联系人姓名\n");
char b[10];
int f = 0;
scanf("%s",b);
for(int i=0;i<now;i++){
if(strcmp(b,a[i].name) == 0){
f++;
printf("修改后的姓名\n");
scanf("%s",&a[i].name);
printf("修改后的性别\n");
scanf("%s",&a[i].sex);
printf("修改后的电话\n");
scanf("%s",&a[i].phone);
printf("修改后的地址\n");
scanf("%s",&a[i].address);
break;
}
}
if(f == 0){
printf("未找到该联系人");
}
printf("如果你想继续修改联系人请按y\n");
printf("或者按任意键退出\n");
getchar();
scanf("%c",&cn);
}while(cn == 'y');
}
void file (){
FILE *f;
if( ( f = fopen("list.txt","w")) == NULL){
printf("打开失败\n");
exit(-1);
}
else{
int i = 0;
while(i<now){
fwrite(&a[i],sizeof(List),1,f);
i++;
}
}
fclose(f);
}
int main (){
copy();
menu();
file();
return 0;
}
- 感想
这是作者第一次写博客,本人是一名在读大学生,希望通过写博客能提高自己,帮助他人,让我们一起成长!!!