/*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co., Ltd.
File name:
Author:Jerey_Jobs Version:0.1 Date:
Description:
Funcion List:
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void get_name(char*);
void get_num(char*,int);
void get_address(char*);
char get_check(char*);
struct node
{
char name[20];
char hometel[9];
char phone[12];
char address[100];
struct node * next;
};
typedef struct node Node;
typedef struct node * Link;
void welcome()
{
printf(" =============================================================================\n");
printf("| |\n");
printf("| 通讯录 |\n");
printf("| |\n");
printf(" =============================================================================\n");
printf("| |\n");
printf("| 1 显示通讯录 2 添加联系人信息 |\n");
printf("| 3 删除联系人信息 4 查找联系人信息 |\n");
printf("| 5 修改联系人信息 6 退出 |\n");
printf("| |\n");
printf(" =============================================================================\n");
printf("\n");
printf("请输入操作对应的数字:");
}
void create_node(Link *new_node)
{
int count = 10;
do
{
*new_node = (Link)malloc(sizeof(Node));
count--;
}while(!is_malloc_ok(*new_node) && count);
}
void create_link(Link *head)
{
create_node(head);
(*head)->next = NULL;
}
int is_malloc_ok(Link new_node)
{
if(new_node == NULL)
{
printf("malloc error!\n");
return 0;
}
return 1;
}
void insert_node_and_sort(Link head,Link new_node)
{
Link p = head->next;
Link q = head;
if(p == NULL)
{
new_node->next = head->next;
head->next = new_node;
}
else
{
while(p != NULL && strcmp(p->name,new_node->name) < 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
new_node->next = p;
q->next = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
}
void display(Link head)
{
if(head == NULL)
{
printf("链表已经完全释放!\n");
return;
}
Link p = head->next;
if(p == NULL)
{
printf("通讯录为空!\n");
}
else
{
printf("\t联系人姓名\t座机号\t\t手机号\t\t家庭地址\n");
printf("-------------------------------------------------------------\n");
while(p != NULL)
{
printf("\t%s\t\t%s\t%s\t%s\n",p->name,p->hometel,p->phone,p->address);
p = p->next;
}
}
}
void clear_screen()
{
char str;
printf("\n已成功执行,请按回车键继续操作\n");
my_get(&str,1);
system("clear");
welcome();
}
void create_new_contact(Link head,Link *new_node)
{
char str[2];
do{
create_node(new_node);
printf("请输入新联系人的\n姓 名 :");
get_name((*new_node)->name);
// scanf("%s",(*new_node)->name);
printf("座 机 号 :");
get_num((*new_node)->hometel,9);
// scanf("%s",(*new_node)->hometel);
printf("手 机 号 :");
get_num((*new_node)->phone,12);
// scanf("%s",(*new_node)->phone);
printf("家 庭 地 址:");
// scanf("%s",(*new_node)->address);
get_address((*new_node)->address);
insert_node_and_sort(head,*new_node);
printf("\n保存成功!是否要继续输入?(Y/N):");
get_check(str);
printf("\n");
}while(strcmp(str,"Y") == 0);
}
void delete_contact(Link head)
{
char str[20];
char str1[2];
do
{
printf("请输入你想删除的联系人的姓名:");
//scanf("%s",str);
get_name(str);
//delete_node(head,str);
///
Link p = head->next;
Link q=head;
while(p != NULL && strcmp(p->name,str) != 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
printf("\n抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
}
else
{
q->next = p->next;
free(p);
}
///
printf("\n是否继续删除?(Y/N):");
get_check(str1);
printf("\n");
}while(strcmp(str1,"Y") == 0);
}
void delete_node(Link head,char str[])
{
Link p = head->next;
Link q=head;
while(p != NULL && strcmp(p->name,str) != 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
}
else
{
q->next = p->next;
free(p);
printf("删除成功!");
}
}
void find_contact(Link head)
{
char str[20];
char str1[2];
Link p = head->next;
do{
printf("请输入你想查找的联系人的姓名:");
//scanf("%s",str);
get_name(str);
while(p != NULL && strcmp(str,p->name) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想查找的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
}
printf("\n是否继续查询?(Y/N):");
get_check(str1);
printf("\n");
}while(strcmp(str1,"Y") == 0);
}
void alter_contact(Link head)
{
char str[20];
char str1[50];
char str2[2];
char str3[2];
int num;
Link p =head->next;
do
{
printf("1 按姓名修改 2 按座机号修改\n请输入选项: ");
//scanf("%d",&num);
num = get_mode(str3,2);
switch(num)
{
case 1:
printf("请输入你想修改的联系人的姓名:");
//scanf("%s",str);
get_name(str);
while(p != NULL && strcmp(str,p->name) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
printf("请修改:\n");
printf("请输入联系人的\n姓 名 :");
get_name(p->name);
printf("座 机 号 :");
get_num(p->hometel,9);
printf("手 机 号 :");
get_num(p->phone,12);
printf("家 庭 地 址:");
get_address(p->address);
}
break;
case 2:
printf("请输入你想修改的联系人的座机号:");
get_num(str,9);
while(p != NULL && strcmp(str,p->hometel) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
printf("请修改:\n");
printf("请输入联系人的\n姓 名 :");
get_name(p->name);
printf("座 机 号 :");
get_num(p->hometel,9);
printf("手 机 号 :");
get_num(p->phone,12);
printf("家 庭 地 址:");
get_address(p->address);
}
break;
}
printf("\n是否继续修改?(Y/N):");
get_check(str2);
printf("\n");
}while(strcmp(str2,"Y") == 0);
}
int my_get(char str[],int length) //length为存放的最长长度
{
int i;
for(i = 0; i < length ; i++)
{
str[i] = getchar();
if(str[i] == '\n')
{
str[i] = '\0';
return i;
}
}
while(getchar() != '\n');
str[i - 1] = '\0';
return -1;
}
int check_name(char *str)
{
char *p = str;
if(*p == '\0') //不加的话,如果输入姓名直接打回车键它是会认为没有错的。
{ //因为my_get会把回车改为'\0',而姓名输入又不像数字输入一样有长度限制(就是确定的长度)
return 0;
}
while(*p != '\0')
{
if(!((*p >= 'a' && *p <= 'z') || (*p >= 'A' &&*p <= 'Z')))
{
return 0;
}
p++;
}
return 1;
}
int check_num(char *str)
{
char *p = str;
while(*p != '\0')
{
if(!(*p >= '0' && *p <= '9'))
{
return 0;
}
p++;
}
return 1;
}
int check_mode(char *str,int num)
{
if(*str >= '1' && *str <= '0'+num)
{
return 1;
}
return 0;
}
int check_check(char *str)
{
if(*str == 'Y' || *str == 'N')
{
return 1;
}
return 0;
}
void get_name(char *str)
{
while(my_get(str,20) == -1 || check_name(str) == 0)
{
if(check_name(str) == 0)
{
printf("姓名中出现除大小写以外字母,");
}
else
{
printf("姓名太长超出规定范围,");
}
printf("格式不符合要求,请重新输入:");
}
}
void get_num(char *str, int length)
{
while(my_get(str,length) != length - 1 || check_num(str) == 0)
{
if(check_num(str) == 0)
{
printf("出现非数字的字符,");
}
else
{
printf("需输入%d位的号码,", length - 1);
}
printf("格式不符合要求,请重新输入:");
}
}
void get_address(char *str)
{
while(my_get(str,100) == -1)
{
printf("地址太长超出规定范围,请重新输入:");
}
}
int get_mode(char *str,int num)
{
while(my_get(str,2) == -1 || check_mode(str,num) == 0)
{
printf("请输入1-%d之间的数字:",num);
}
return *str - '0';
}
char get_check(char *str)
{
while(my_get(str,2) == -1 || check_check(str) == 0)
{
printf("请输入Y或N:");
}
return *str;
}
int read_file(Link head,Link *new_node)
{
Node node_data;
FILE *fp;
fp = fopen("AddressList.txt","r");
if(fp == NULL)
{
perror("fopen fail:");
return 0;
}
while(fread(&node_data,sizeof(Node),sizeof(node_data)/sizeof(Node),fp) > 0)
{
create_node(new_node);
strcpy((*new_node)->name,node_data.name);
strcpy((*new_node)->hometel,node_data.hometel);
strcpy((*new_node)->phone,node_data.phone);
strcpy((*new_node)->address,node_data.address);
insert_node_and_sort(head,*new_node);
memset(&node_data,0,sizeof(node_data));
}
fclose(fp);
return 1;
}
int write_file(Link head)
{
Link p = head->next;
Node node_data;
FILE *fp;
fp = fopen("AddressList.txt","w");
int ret;
if(fp == NULL)
{
perror("fopen fail:");
return 0;
}
if(p == NULL)
{
return 1;
}
else
{
while(p != NULL)
{
ret = fwrite(p,sizeof(Node),sizeof(node_data)/sizeof(Node),fp);
if(ret != sizeof(node_data)/sizeof(Node))
{
perror("fwrite error:");
return 0;
}
p = p->next;
}
}
fclose(fp);
return 1;
}
int main()
{
system("clear");
welcome();
Link head;
Link new_node;
int num;
char num_get[2];
int flag = 1;
create_link(&head);
read_file(head,&new_node);
while(flag)
{
num = get_mode(num_get,6);
switch(num)
{
case 1:
display(head);
clear_screen();
break;
case 2:
create_new_contact(head,&new_node);
clear_screen();
break;
case 3:
delete_contact(head);
clear_screen();
break;
case 4:
find_contact(head);
clear_screen();
break;
case 5:
alter_contact(head);
clear_screen();
break;
case 6:
flag = 0;
break;
}
}
write_file(head);
return 0;
}