Linux C编程 简单电话薄(从文件中读取记录,支持插入、删除和保存操作)

/*
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;
}




运行结果:

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值