结合链表和文件保存再次写通讯录~~~~
/*************************************************************************
> File Name: LinkList.h
> Author: cy
> Function List: main() 主函数
> Created Time: 2018年02月04日 星期日 09时41分34秒
************************************************************************/
#ifndef _TONGXUNLU_H_
#define _TONGXUNLU_H_
#define size 50
#define success 0
#define failure 1
struct person
{
//数据域
int num;
char name[size];
char tel[size];
char phone[size];
char address[size];
struct person *next; //指针域
};
typedef struct person Person;
typedef Person *Per;
void welcome();
void menu();
void menu1();
void addperson(Per l); //添加联系人
void listperson(Per l);
void searchperson(Per l);
void modifyperson(Per l);
void deleteperson(Per l);
Per myread();
#endif
/*************************************************************************
> File Name: LinkList.c
> Author: cy
> Function List: main() 主函数
> Created Time: 2018年02月04日 星期日 09时44分41秒
************************************************************************/
#include<stdio.h>
#include"tongxulu.h"
#include<string.h>
#include<stdlib.h>
void welcome()
{
system("clear");
printf("\t\t\t******************************************************\n\n");
printf("\t\t\t\t\t\tWELCOME\n\n");
printf("\t\t\t******************************************************\n\n");
sleep(2);
}
void menu()
{
system("clear");
printf("\t\t\t********************************************************\n");
printf("\t\t\t***********************主菜单***************************\n\n");
printf("\t\t\t\t1、增加联系人 2、显示联系人\n");
printf("\t\t\t\t3、查询联系人 4、修改联系人\n");
printf("\t\t\t\t5、删除联系人 6、退出\n\n");
printf("\t\t\t********************************************************\n\n");
printf("请选择:\n");
}
void menu1()
{
system("clear");
printf("\t\t************************************************************\n");
printf("\t\t************************修改菜单****************************\n\n");
printf("\t\t1、输入要修改联系人的姓名 2、显示联系人信息\n");
printf("\t\t3、修改联系人编号 4、修改联系人姓名\n");
printf("\t\t5、修改联系人手机 6、修改联系人住宅电话\n");
printf("\t\t7、修改联系人地址 8、退出\n\n");
printf("\t\t************************************************************\n\n");
printf("请选择:\n");
}
int checknum(Per l,int n) //输入的编号n是否存在
{
Per r;
r = l; //头结点
while (r->next != NULL)
{
r = r->next;
if (n == r->num)
{
printf("输入的编号已存在,请核实后重新输入!\n");
return failure;
}
}
return success;
}
int checkname(Per l,char *s) //核实名字
{
Per r = l; //头结点赋给r
while(r->next != NULL) //第一结点不为空
{
r = r->next;
if (0 == strcmp(s,r->name))
{
printf("联系人已存在,请核实后重新输入!\n");
return failure;
}
}
return success;
}
int checkphone(Per l,char *s) //核实手机
{
char *t = s;
Per r = l;
if (strlen(s) != 11)
{
printf("输入的号码长度有误,请重新输入11位号码!\n");
return failure;
}
while(r->next != NULL) //第一结点不为空
{
r = r->next;
if (0 == strcmp(s,r->phone))
{
printf("此号码已存在,请核实后重新输入!\n");
return failure;
}
}
while(*t != '\0')
{
if (*t < 48 || *t > 57) //大于9.小于0
{
printf("输入的号码中不可有字符,请核实后重新输入!\n");
return failure;
}
t++;
}
return success;
}
int checktel(Per l,char *s) //核实电话号码
{
char *t = s;
Per r = l;
if (strlen(s) != 8)
{
printf("输入的号码长度有误,请重新输入8位号码!\n");
return failure;
}
while(r->next != NULL) //第一结点不为空
{
r = r->next;
if (0 == strcmp(s,r->tel))
{
printf("此号码已存在,请核实后重新输入!\n");
return failure;
}
}
while(*t != '\0')
{
if (*t < 48 || *t > 57) //大于9.小于0
{
printf("输入的号码中不可有字符,请核实后重新输入!\n");
return failure;
}
t++;
}
return success;
}
void sortname(Per l,Per p)
{
if (l->next == NULL || strcmp(l->next->name,p->name) >= 0) //第一结点大于新结点的数据
{
p->next = l->next; //p的下一个等于l的下一个
l->next = p; //把p的数据插到l,l->next中间
}
else
{
Per r = l->next; //第一结点
while (r->next != NULL && strcmp(r->next->name,p->name) < 0)
//第一结点小于新节点
{
r = r->next; //
}
p->next = r->next;
r->next = p; //新的数据插入r的后一个
}
}
void Save(Per l)
{
FILE *fp; //定义一个文件指针,接收fopen的返回值
Per t = l->next; //定义一个指针,遍历链表,向文件内写入
if ((fp = fopen("telephone.txt","w+")) == NULL)
{
perror("open");
exit(1);
}
while(t != NULL)
{
fwrite(t,sizeof(Person),1,fp); //写入文件
t = t->next;
}
fclose(fp);
printf("文件保存成功\n");
}
Per myread()
{
FILE *fp;
Per head = NULL, t1, t2; //头指针用于保存返回值,t1,t2临时指针
char c;
fp = fopen("telephone.txt","r");
if (NULL == fp)
{
perror("open");
exit(1);
}
c = fgetc(fp); //返回值是文件的第一个字符,当文件为空的时候,他返回的是一个特殊值:EOF
if (EOF == c) // 文件为空
{
return NULL;
}
else
{
rewind(fp); //把文件的位置指针重新移至开头
}
head = (Per)malloc(sizeof(Person));
t1 = (Per)malloc(sizeof(Person));
if (NULL == t1)
{
perror("malloc failure!");
}
fread(t1,sizeof(Person),1,fp);
head->next = t1;
while(1)
{
Per temp = (Per)malloc(sizeof(Person));
int ret = fread(temp,sizeof(Person),1,fp);
if(ret == 0)
{
t1->next = NULL;
break;
}
t1->next = temp;
t1 = t1->next;
}
fclose(fp);
printf("文件已成功读取!\n");
return head; //没有创建一个单链表和文件的时候,就是靠这个头指针进行一系列的操作的
}
void addperson(Per l)
{
Per p;
p = (Per)malloc(sizeof(Person));
if (p == NULL)
{
printf("malloc failure!\n");
}
printf("请输入联系人编号:\n");
scanf("%d",&p->num);
//printf("Test: p->num= %d\n", p->num);
// printf("Test: check(l ,p->num)= %d\n", checknum(l, p->num));
while(failure == checknum(l,p->num))
{
printf("请重新输入编号:\n");
scanf("%d",&p->num);
}
printf("请输入联系人姓名:\n");
scanf("%s",p->name);
while(failure == checkname(l,p->name))
{
printf("请重新输入联系人姓名:\n");
scanf("%s",p->name);
}
printf("请输入联系人手机号码:\n");
scanf("%s",p->phone);
while(failure == checkphone(l,p->phone))
{
printf("请重新输入联系人手机号码:\n");
scanf("%s",p->phone);
}
printf("请输入联系人住宅电话:\n");
scanf("%s",p->tel);
while(failure == checktel(l,p->tel))
{
printf("请重新输入联系人住宅电话:\n");
scanf("%s",p->tel);
}
printf("请输入联系人地址:\n");
scanf("%s",p->address);
sortname(l,p); //排序插入
getchar();
printf("输入成功!\n");
getchar();
}
void listperson(Per l)
{
Per r = l;
if (r->next == NULL)
{
printf("通讯录中无联系人,请先添加联系人!\n");
}
while(r->next != NULL)
{
r = r->next;
printf("编号: %d 姓名: %s 手机号码: %s 住宅电话: %s 地址: %s\n",r->num, r->name,
r->phone, r->tel, r->address);
}
printf("请按回车键返回");
getchar();
getchar();
}
void searchperson(Per l)
{
int i = 0;
Per r = l;
if (NULL == r->next)
{
printf("通讯录为空,请先添加联系人!\n");
}
char s[10] = {0};
printf("请输入要查找的联系人姓名:\n");
scanf("%s",s);
while(r->next != NULL)
{
r = r->next;
if (0 == strcmp(s,r->name))
{
printf("编号: %d 姓名: %s 手机号码: %s 住宅电话: %s 地址: %s\n",r->num,
r->name, r->phone, r->tel, r->address);
i++;
}
else
{
continue;
}
}
if (0 == i)
{
printf("该通讯录中没有名为 %s 的联系人!\n",s);
}
printf("请按回车键返回!\n");
getchar();
getchar();
}
void modifyperson(Per l)
{
int num;
char choice[10] = {0};
char s[10] = {0};
Per q = l;
if (NULL == l->next)
{
printf("通讯录为空,请先添加联系人");
sleep(2);
}
while(1)
{
menu1();
scanf("%s",choice);
if (1 == strlen(choice))
{
switch(choice[0])
{
case '1':{
printf("请输入联系人姓名:\n");
scanf("%s",s);
q = l->next;
while(strcmp(q->name,s) != 0 && q->next != NULL)
{
q = q->next;
}
if (strcmp(q->name,s) != 0) //比较到最后一个
{
printf("该联系人不存在,请查实后重新上输入!\n");
}
printf("按回车键继续\n");
getchar();
getchar();
break;
}
case '2':{
printf("编号: %d 姓名: %s 手机号码: %s 住宅电话: %s 地址: %s\n",q->num, q->name, q->phone, q->tel, q->address);
printf("按回车键继续");
getchar();
getchar();
break;
}
case '3':{
printf("请输入编号:\n");
scanf("%d",&num);
while(failure == checknum(l,num))
{
printf("输入的编号已存在,请重新输入:\n");
scanf("%d",&num);
}
q->num = num;
printf("按回车键继续");
getchar();
getchar();
break;
}
case '4':{
printf("请输入姓名:\n");
scanf("%s",s);
while(failure == checkname(l,s))
{
printf("输入的姓名已存在,请查证后重新输入!\n");
scanf("%s",s);
}
strcpy(q->name,s);
printf("按回车键继续");
getchar();
getchar();
break;
}
case '5':{
printf("请输入新的手机号码!\n");
scanf("%s",s);
while(failure == checkphone(l,s))
{
printf("输入的号码已存在,请查证后重新输入!\n");
scanf("%s",s);
}
strcpy(q->phone,s);
printf("按回车键继续");
getchar();
getchar();
break;
}
case '6':{
printf("请输入新的住宅号码!\n");
scanf("%s",s);
while(failure == checktel(l,s))
{
printf("输入的号码已存在,请查证后重新输入!\n");
scanf("%s",s);
}
strcpy(q->tel,s);
printf("按回车键继续");
getchar();
getchar();
break;
}
case '7':{
printf("请输入新的地址!\n");
scanf("%s",s);
strcpy(q->address,s);
printf("按回车键继续");
getchar();
getchar();
break;
}
case '8':{
break;
}
default:{
while(getchar() != '\n');
printf("输入错误,按回车键返回");
getchar();
break;
}
}//switch
if ('8' == choice[0])
{
//printf("返回主菜单");
break;
}
continue;
}//if
}//while
}//void
void deleteperson(Per l)
{
Per r = l, q;
char s[10] = {0};
if (NULL == l->next)
{
printf("通讯录中没有联系人!\n");
getchar();
}
printf("请输入要删除的联系人姓名:\n");
scanf("%s",s);
while(r->next != NULL)
{
if (0 == strcmp(r->next->name,s))
{
q = r->next;
r->next = q->next;
free(q);
printf("删除联系人成功!\n");
getchar();
getchar();
return;
}
r = r->next;
}
printf("姓名为 %s 的联系人不存在!\n",s);
getchar();
getchar();
}
/************************************************************************
> File Name: toxulu.c
> Author: cy
> Function List: main() 主函数
> Created Time: 2018年02月06日 星期二 21时58分50秒
************************************************************************/
#include<stdio.h>
#include"tongxulu.h"
#include<string.h>
#include<stdlib.h>
int main()
{
Per head, temp;
head = (Per)malloc(sizeof(Person));
temp = head;
head = myread();
if(NULL == head)
{
head = temp;
}
char choice[10];
welcome();
while(1)
{
menu();
scanf("%s",&choice);
if (1 == strlen(choice))
{
switch(choice[0])
{
case '1':
addperson(head);
break;
case '2':
listperson(head);
break;
case '3':
searchperson(head);
break;
case '4':
modifyperson(head);
break;
case '5':
deleteperson(head);
break;
case '6':
Save(head);
exit(0);
break;
default:
{
while(getchar() != '\n');
printf("输入错误,按回车键返回");
getchar();
break;
}
}//switch
continue;
}//if
else
{
while(getchar() != '\n');
printf("输入错误,按回车键返回");
getchar();
continue;
}
}//while
return 0;
}