/*
Function: A small phonebook
Author: nuaazdh
Date:11-1,2011
Revised: 6-2,2013
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>
#define NAMELEN 16
#define PHONELEN 11
#define EMAILLEN 28
#define BUFFERSIZE 100
#define YES 1
#define NO 0
/*关系类型*/
enum Relation
{
FAMILY,FRIEND,CALSSMEATE,TEACHER,OTHER
};
/*节点结构体*/
struct RecordNode
{
/*pointer struct*/
char *name;
char *phonenum;
char *email;
/*array struct
char name[NAMELEN];
char phonenum[PHONELEN];
char email[EMAILLEN];*/
enum Relation relation;
struct RecordNode *next;
};
/*函数原型*/
void ShowWelcome();
void ShowBye();
struct RecordNode *Create();
struct RecordNode *CreateNew();
char SelectOperation();
struct RecordNode * Insert(struct RecordNode *head,struct RecordNode *newnode);
void ShowAll(struct RecordNode *head);
void ShowNode(struct RecordNode *node);
struct RecordNode *Delete(struct RecordNode *head);
void Save(struct RecordNode *head);
char *CatNode(struct RecordNode *node);
int strlen(char *src);
int AllNum(char *src);
int IsNum(const char c);
int IsChar(const char c);
struct RecordNode* ReadNode(char *file);
/*主函数*/
int main()
{
ShowWelcome();
struct RecordNode *head=Create();
char op=SelectOperation();
while(1)
{
if('a'==op){
struct RecordNode *newnode = CreateNew();
head=Insert(head,newnode);
}
else if('d'==op){
head=Delete(head);
}
else if('s'==op){
ShowAll(head);
}
else if('v'==op){
Save(head);
}
else if('q'==op){
break;
}
else{
;
}
printf(">>");/*print */
scanf("%s",&op);/*only get the first letter*/
op=tolower(op);
//op=getch();
}
ShowBye();
return 1;
}
/*创建一个新节点,返回指针*/
struct RecordNode *CreateNew()
{
struct RecordNode *node=(struct RecordNode *)malloc(sizeof(struct RecordNode));
node->name=(char *)malloc(sizeof(char)*19);
node->phonenum=(char*)malloc(sizeof(char)*12);
node->email=(char *)malloc(sizeof(char)*41);
printf("Please input the name(less than 16 characters):");
scanf("%s",node->name);
printf("Please input the phone number(11 numbers):");
scanf("%s",node->phonenum);
while(NO==AllNum(node->phonenum))
{
printf("Sorry,invalid phone number.Please input again or 'q' to escape:");
scanf("%s",node->phonenum);
if('q'==*node->phonenum)
return NULL;
}
printf("Please input the emain address(less than 40 characters):");
scanf("%s",node->email);
node->next=NULL;
return node;
}
/*获取用户选择*/
char SelectOperation()
{
char input;
printf("Please input your opeartion(first letter is valid):\n");
printf("a: Add a new account\n");
printf("d: Delete a account\n");
printf("s: Show all records\n");
printf("v: Save all records\n");
printf("q: Quit\n");
printf("others: Do nothing.\n");
printf(">>");
scanf("%s",&input);
//input=getchar();
input=tolower(input);/*transfer to lower case*/
return input;
}
/*插入一个节点,并返回头节点*/
struct RecordNode *Insert(struct RecordNode *head,struct RecordNode *newnode)
{
if(newnode==NULL)
return head;/*return directly*/
if(head==NULL){
head=newnode;
head->next=NULL;
}else{
struct RecordNode *p=head;
while(p->next!=NULL)
p=p->next;
p->next=newnode;
newnode->next=NULL;
}/*if*/
return head;
}
/*根据编号删除某个节点*/
struct RecordNode *Delete(struct RecordNode *head)
{
if(head==NULL){
printf("Sorry,there is no record.\n");
return NULL;
}
else
printf("Please input the No. your want to delete(from 1):");
int d;
scanf("%d",&d);
struct RecordNode *p=head;
if(d==1){
head=head->next;
/*删除首节点*/
free(p);
}else{/*删除非首节点*/
int i=1;
while(i!=d&&p!=NULL){
i++;p=p->next;
}/*while*/
if(p==NULL){/*删除节点不存在*/
printf("Sorry,the node is not exist.\n");
return head;
}else{
struct RecordNode *pre=head;
while(pre->next!=p)
pre=pre->next;
pre->next=p->next;
free(p);
}
}/*else*/
printf("Delete succeed!\n");
if(head==NULL)
printf("There is no record now\n");
return head;
}
/*循环显示所有节点*/
void ShowAll(struct RecordNode *head)
{
if(head==NULL){
printf("Sorry,there is no record now.\n");
return;
}
printf("Name\t\t");
printf("Phone Number\t");
printf("Email\n");
struct RecordNode *p=head;
while(p!=NULL)
{
ShowNode(p);
p=p->next;
}
printf("\n");
}
/*显示一个节点*/
void ShowNode(struct RecordNode *node)
{
if(node==NULL)
return;
printf("%s\t",node->name);
printf("%s\t",node->phonenum);
printf("%s\n",node->email);
}
/*显示欢迎*/
void ShowWelcome()
{
int i=0;
for(i=0;i<40;i++)
printf("*");
printf("\nWelcome to PhoneBook\n");
printf("by luerfeng, version:1.0\n");
for(i=0;i<40;i++)
printf("*");
printf("\n");
}
/*显示再见*/
void ShowBye()
{
int i=0;
for(i=0;i<40;i++)
printf("*");
printf("\nThank you for ues,GoodBye !\n");
printf("by luerfeng, version:1.0\n");
for(i=0;i<40;i++)
printf("*");
printf("\n");
}
/*建立从文件中建立链表*/
struct RecordNode *Create()
{
char *file = "Phone.txt";
char option;
int fd;
if(access(file,F_OK)==-1)/*file does not exist*/
{
printf("Phone.txt does not exsit,do you want to create?[y/n]:");
option=getchar();
option=tolower(option);/*transfer to lower case*/
if('y'==option)
{
fd=open(file,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
if(fd==-1)
printf("\nSorry,create file failed.\n\n");
else
printf("\nCreate file succeed.\n\n");
close(fd);
}
return NULL;
}
else/*Create link-table from file*/
return ReadNode(file);
}
/*保存所有记录*/
void Save(struct RecordNode *head)
{
int fd;/*file describtion*/
struct RecordNode *ptr=head;
fd=open("Phone.txt",O_TRUNC|O_CREAT|O_RDWR,00666);
if(fd==-1)
{
perror("Sorry,Create or open file failed");
return;
}
if(head==NULL)
{
printf("There is no record now,the file will be cleared.\n");
// open the file and close it to empty the file
close(fd);
return;
}
int count=0;
char *cptr;
int cntw;
while(ptr!=NULL)
{
cptr=CatNode(ptr);
count=strlen(cptr);
/*printf("Record info:%s\n",cptr);*/
if(cptr==NULL)
continue;
while((cntw=write(fd,cptr,count))!=0)
{
if(cntw==-1)
{
printf("Sorry,save failed.\n");
perror("Error Message:");
break;
}
else if(cntw==count)
break;
else if(cntw>0)
{
cptr+=cntw;
count-=cntw;
}
}
ptr=ptr->next;
}
close(fd);
}
/*将当前节点内容转换为带格式的字符串*/
char *CatNode(struct RecordNode *node)
{
if(node==NULL)
return NULL;
//int count=sizeof(node->name)+sizeof(node->phonenum)+sizeof(node->email);
char *cptr=(char *)malloc(60);
char *dst=cptr;
char *p;
p=node->name;
/*printf("%s\n",p);*/
while(*p!='\0')
{
*cptr++=*p++;
}
*cptr++='\t';
p=node->phonenum;
/*printf("%s\n",p);*/
while(*p!='\0')
{
*cptr++=*p++;
}
*cptr++='\t';
p=node->email;
/*printf("%s\n",p);*/
while(*p!='\0')
{
*cptr++=*p++;
}
*cptr++='\r';
*cptr++='\n';
*cptr='\0';
/*printf("%s\n",cptr);*/
return dst;/*return the string*/
}
/*计算字符串长度*/
int strlen(char *src)
{
if(src==NULL)
return 0;
int i=0;/*counter*/
char *p=src;
while(*p!='\0')
{
p++;i++;
}
return i;
}
/*检验字符串是否全为数字,1:全数字,0:不是全数字*/
int AllNum(char *src)
{
char *p=src;
int flag=YES;
while(*p!='\0')
{
if(NO==IsNum(*p))
{
flag=NO;
break;
}
p++;
}
return flag;
}
/*检验某个字符是否为数字,YES:是数字,NO:非数字*/
int IsNum(const char c)
{
if((c>='0')&&(c<='9'))
{
return YES;
}
else
return NO;
}
/*判断字符是否为数字或字母,YES:是,NO:否*/
int IsChar(const char c)
{
if((c<='9'&&c>='0')||(c<='z'&&c>='a')||(c<='Z'&&c>='A'))
return YES;
else
return NO;
}
/*判断字符是否可能出现在邮箱中,YES:可以,NO:不可以*/
int IsEmailChar(const char c)
{
if(IsChar(c)||('@'==c)||('_'==c)||('.'==c)||('-'==c))
return YES;
else
return NO;
}
/*从文件中读取记录,返回链表头指针*/
struct RecordNode* ReadNode(char *file)
{
FILE *fp;
struct RecordNode *head=NULL;
fp=fopen(file,"r");
if(fp==NULL)
{
printf("Sorry,read file failed.\n");
return head;
}
char buffer[BUFFERSIZE];
//char *fptr;
char *p,*q;
struct RecordNode* newnode;
while(fgets(buffer,BUFFERSIZE,fp)!=NULL)
{
/*apply for a new node*/
newnode=(struct RecordNode*)malloc(sizeof(struct RecordNode));
p=buffer;
if(newnode==NULL)
{
printf("Memory apply error.\n");
break;
}
/*get name*/
newnode->name=(char *)malloc(sizeof(char)*NAMELEN);
q=newnode->name;
while(YES==IsChar(*p))
{
*q++=*p++;
}
*q='\0';
while(NO==IsChar(*p)) p++;
/*get phonenum*/
newnode->phonenum=(char *)malloc(sizeof(char)*PHONELEN);
q=newnode->phonenum;
while(YES==IsChar(*p))
{
*q++=*p++;
}
*q='\0';
while(NO==IsChar(*p)) p++;
/*get email*/
newnode->email=(char *)malloc(sizeof(char)*EMAILLEN);
q=newnode->email;
while(YES==IsEmailChar(*p))
{
*q++=*p++;
}
*q='\0';
head=Insert(head,newnode);
}
fclose(fp);
return head;
}
运行结果: