用链表实现通讯录,并保存到文件。
包含的功能有:1、添加好友;2、查看列表;3、删除好友;4、查找好友;5、修改信息;6、保存退出。
在进入时读取文件中的联系人信息,再退出时重新保存。
头文件:
#ifndef _STRUCT_H_
#define _STRUCT_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int i; //定义全局变量i
struct node
{
int ID;
char name[20];
char ismale[20];
char tel[20];
char qq[20];
char address[20];
char remark[20]; //保存联系人信息
struct node *next; //结构体类型的指针,保存下一个结构体的地址
};
void clear();
void interface();
void read_data(struct node *header);
int insert_tail( struct node *header );
void printfcon( struct node *header, int j );
void list( struct node *header );
int findnum( struct node *header, char *s, int *accumlate );
void seek( struct node *header );
int coverdata( struct node *header, int j );
void mydelete( struct node *header );
void setid( struct node *header );
int modify( struct node *header, int j );
void revise( struct node *header );
void write_data(struct node *header);
#endif
有关文件操作的函数:
#include "struct.h"
void read_data(struct node *header)
{
FILE *fp = fopen("Maillist", "ab+");
if (fp == NULL)
{
perror ("fopen");
return;
}
struct node *temp = header;
// 读记录的个数
fread (&i, sizeof(int), 1, fp);
int j;
for (j = 0; j < i; j++)
{
int len;
fread (&len, sizeof(int), 1, fp);
struct node *p = (struct node *)malloc(sizeof(struct node));
if( p == NULL )
{
printf("malloc error!\n");
return ;
}
// 读取数据
int ret = fread (p, len, 1, fp);
printf("%d\n",ret);
while( temp->next != NULL )
{
temp = temp->next;
}
temp->next = p; //找到最后一个结点,将结点p尾插进链表
p->next = NULL;
}
fclose(fp);
}
void write_data(struct node *header)
{
FILE *fp = fopen("Maillist", "wb+");
if (fp == NULL)
{
perror ("fopen");
return;
}
// 要写入个数
fwrite(&i, sizeof(int), 1, fp);
struct node *p = header;
while( p->next != NULL )
{
p = p->next;
// 写入数据长度
int len = sizeof(struct node);
fwrite(&len, sizeof(int), 1, fp);
// 写入数据
fwrite(p, len, 1, fp);
}
fclose(fp);
}
插入联系人信息:
#include "struct.h"
int insert_tail( struct node *header ) //定义添加联系人函数
{
char c = 0;
struct node *temp = header;
do
{
clear();
struct node *p = (struct node *)malloc(sizeof(struct node));
if( p == NULL )
{
printf("malloc error!\n");
return -1;
}
printf("请输入联系人姓名:"); //录入联系人信息
scanf("%s",p->name);
printf("请输入联系人性别:");
scanf("%s",p->ismale);
printf("请输入联系人电话号码:");
scanf("%s",p->tel);
printf("请输入联系人QQ号:");
scanf("%s",p->qq);
printf("请输入联系人家庭地址:");
scanf("%s",p->address);
printf("备注:");
scanf("%s",p->remark);
p->ID = i;
i++; //录完后让i++
while( temp->next != NULL )
{
temp = temp->next;
}
temp->next = p; //找到最后一个结点,将结点p尾插进链表
p->next = NULL;
printf("是否继续添加? (y/n) :");
__fpurge(stdin); //清除缓冲区
c = getchar();
}while( c == 'y' ); //do while语句,当c不等于y时退出循环,即不再继续添加
}
查看联系人列表:
#include "struct.h"
void list( struct node *header ) //定义联系人列表函数,输出所有联系人信息
{
clear();
int j = 0;
for( j = 0; j <= i; j++ )
{
printfcon( header, j ); // 调用printfcon函数,输出每个联系人的信息
}
}
void printfcon(struct node *header, int j) //定义打印单个联系人信息函数
{
struct node *p = header;
while( p->next != NULL )
{
p = p->next;
if( p->ID == j )
{
printf("编号:%d\n",p->ID); //遍历链表,输出ID为j的联系人信息
printf("姓名:%s\n",p->name);
printf("性别:%s\n",p->ismale);
printf("电话:%s\n",p->tel);
printf("QQ号:%s\n",p->qq);
printf("地址:%s\n",p->address);
printf("备注:%s\n",p->remark);
printf("\n");
}
}
}
删除联系人:
#include "struct.h"
void mydelete( struct node *header ) //定义删除联系人函数
{
char c = 0;
struct node *p = header;
do
{
clear();
int j = 0;
int temp = 0;
int accum = 0;
int a[20] = {0};
char name[20] = {0};
printf("请输入你想删除的联系人的姓名:");
scanf("%s",name);
accum = findnum( p, name, a ); //调用findnum函数,并把找到几个联系人赋给accum
if( accum == 0 )
{
printf("此联系人不存在!\n");
}
else if( accum == 1 )
{
temp = a[0];
printfcon( p, temp );
coverdata( p, temp );
}
else if( accum > 1 )
{
printf("有%d个联系人!\n",accum); //如果找到不止一个联系人,一个个输出这些联系人信息,让操作者选择是否要删除
for( j = 0; j < accum; j++ )
{
temp = a[j];
printfcon( p, temp );
coverdata( p, temp );
}
}
setid( p );
printf("是否继续删除? (y/n): \n");
__fpurge(stdin);
c = getchar();
}while( c == 'y' ); //do while语句,用来控制是否继续删除,只有输入y时才继续删除
}
int coverdata( struct node *header, int j ) //定义覆盖信息函数
{
printf("是否删除该联系人?(y/n)\n");
__fpurge(stdin);
if( getchar() == 'y' ) //当输入的字符为y时执行操作
{
struct node *prev = NULL;
struct node *p = header;
while( p->next != NULL )
{
prev = p;
p = p->next;
if( p->ID == j )
{
prev->next = p->next;
printf("删除成功!\n");
printf("\n");
free(p);
p = NULL;
i--;
return 0; //当ID等于j时,让p前一个结点指向p后一个结点,释放p,让i-1
}
}
printf("delete error!\n");
}
}
void setid( struct node *header )
{
struct node *p = header;
int j = 0;
while( p->next !=NULL )
{
p = p->next; //跳过头结点或指向下一个结点
p->ID = j++; //重置每个结点的ID
}
}
查找联系人:
#include "struct.h"
void seek( struct node *header ) //定义查找函数,通过姓名查找
{
char c = 0;
struct node *p = header;
do
{
clear();
int j = 0;
int temp = 0;
int accum = 0;
int a[20] = {0};
char name[20] = {0};
printf("请输入你想查找的联系人的姓名:");
scanf("%s",name);
accum = findnum( p, name, a ); //调用findnum函数,并把找到几个联系人赋给accum
if( accum == 0 )
{
printf("此联系人不存在!\n");
}
else if( accum == 1 ) //如果找到一个联系人,输出这个联系人的信息
{
temp = a[0];
printfcon( p, temp );
}
else if( accum > 1 ) //找到不止一个联系人,输出全部联系人信息
{
printf("有%d个联系人!\n",accum);
for( j = 0; j < accum; j++ )
{
temp = a[j];
printfcon( p, temp );
}
}
printf("是否继续查找? (y/n) :");
__fpurge(stdin);
c = getchar();
}while( c == 'y' ); //do while语句用来控制是否继续查找,当输入为y时继续查找
}
int findnum( struct node *header, char *s, int *accumlate ) //定义找到联系人编号函数,找到编号存入数组accumlate
{
int m = 0;
int j = 0;
struct node *p = header;
for( m = 0; m <= i; m++ )
{
if( strcmp( s, p->name ) == 0 )
{
accumlate[j++] = p->ID; //比较字符串s和p->name,如果返回值为0,代表相等,把p->ID存入数组
}
p = p->next;
}
return j; //返回数组中有几个值,即能找到几个联系人
}
修改联系人信息:
#include "struct.h"
void revise( struct node *header ) //定义修改信息函数
{
char c = 0;
struct node *p = header;
do
{
clear();
int j = 0;
int temp = 0;
int accum = 0;
int a[20] = {0};
char name[20] = {0};
printf("请输入你想修改的联系人的姓名:");
scanf("%s",name);
accum = findnum( p, name, a );
if( accum == 0 )
{
printf("此联系人不存在!\n");
}
else if( accum == 1 )
{
temp = a[0];
printfcon( p, temp );
modify( p, temp );
}
else if( accum > 1 )
{
printf("有%d个联系人!\n",accum);
for( j = 0; j < accum; j++ )
{
temp = a[j];
printfcon( p, temp ); //有不止一个联系人时一个个输出联系人信息,让其修改
modify( p, temp );
}
}
printf("是否继续修改? (y/n) :\n");
__fpurge(stdin);
c = getchar();
}while( c == 'y' ); //do while语句用来控制是否继续修改,当输入y时继续循环修改
}
int modify( struct node *header, int j ) //定义修改函数
{
int temp = 0;
int rev = 1;
struct node *p = header;
while( p->next != NULL )
{
p = p->next;
if( p->ID == j )
{
printf("1--姓名\n");
printf("2--性别\n");
printf("3--电话\n");
printf("4--qq号\n");
printf("5--住址\n");
printf("6--备注\n");
printf("请输入你要修改的项:\n");
do
{
rev = 1;
__fpurge(stdin);
if(scanf("%d",&temp) != 1)
{
printf("输入错误!请重新输入!\n");
rev = -1;
}
else if( temp >= 7 || temp <= 0 )
{
printf("输入错误!请重新输入!\n");
rev = -1; //当选择的值没有传入或者不为1-6时。输出输入错误请重输
}
}while( rev == -1 );
switch(temp) //用switch语句选择要修改的信息
{
case 1:{
printf("请输入你要改成的姓名:");
scanf("%s",p->name);
printf("修改成功!\n");
printf("\n");
break;
}
case 2:{
printf("请输入你要改成的性别:");
scanf("%s",p->ismale);
printf("修改成功!\n");
printf("\n");
break;
}
case 3:{
printf("请输入你要改成的电话:");
scanf("%s",p->tel);
printf("修改成功!\n");
printf("\n");
break;
}
case 4:{
printf("请输入你要改成的qq号:");
scanf("%s",p->qq);
printf("修改成功!\n");
printf("\n");
break;
}
case 5:{
printf("请输入你要改成的住址:");
scanf("%s",p->address);
printf("修改成功!\n");
printf("\n");
break;
}
case 6:{
printf("请输入你要改成的备注:");
scanf("%s",p->remark);
printf("修改成功!\n");
printf("\n");
break;
}
default:printf("输入错误!\n");
break;
}
}
}
}
main函数:
#include "struct.h"
void clear()
{
system("clear"); //清屏
}
void interface() //界面函数,输出主界面
{
printf(" *********************************************************************************\n");
printf(" * *\n");
printf(" * *\n");
printf(" | |\n");
printf(" | 通 讯 录 |\n");
printf(" | |\n");
printf(" | ~~~~~~~~ |\n");
printf(" | 1、添加好友; |\n");
printf(" | 2、查看列表; |\n");
printf(" | 3、删除好友; |\n");
printf(" | 4、查找好友; |\n");
printf(" | 5、修改信息; |\n");
printf(" | 6、保存退出; |\n");
printf(" | ~~~~~~~~ |\n");
printf(" | |\n");
printf(" | 请在下面输入1、2、3、4、5、6选择你的操作. |\n");
printf(" | |\n");
printf(" * *\n");
printf(" * *\n");
printf(" *********************************************************************************\n");
}
int main()
{
struct node *header = (struct node *)malloc(sizeof(struct node)); //定义头指针
if( header == NULL )
{
printf("malloc error!\n");
return -1;
}
read_data(header);
while(1)
{
int temp = 0;
clear();
interface(); //调用interface函数,输出主界面
__fpurge(stdin);
scanf("%d",&temp);
switch(temp) //switch语句选择功能
{
case 1:{
insert_tail( header );
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar();
break;
}
case 2:{
list( header );
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar(); //暂停界面,有输入才退出本次选择语句
break;
}
case 3:{
mydelete( header );
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar();
break;
}
case 4:{
seek( header );
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar();
break;
}
case 5:{
revise( header );
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar();
break;
}
case 6:{
write_data( header );
exit(0);
}
default:{
printf("输入错误!");
printf("按enter返回主界面!\n");
__fpurge(stdin);
getchar();
break;
}
}
}
return 0;
}