C语言小功能实现--通讯录功能

/*****************************************************************
*   Copyright (C) 2018 SuQian Ltd. All rights reserved.
*   
*   文件名称:myllist.c
*   创 建 者:yulei
*   创建日期:2018年02月03日
*   描    述:
*
*****************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
#define fname "txl.db"
#define TRUE 1
#define FALSE 0
#define Status int

typedef struct         //定义联系人数据结构
{  char name[10];
   char addr[30];
   char mphone[12];
   char tel[12];
   char sex;
   unsigned char age;
}DataType;

typedef struct Node     //存放联系人信息,链表格式
{  DataType data;
   struct Node *next;
}Node;

typedef Node *llist;
  

char *mainmenu[]={                 //下面是各种菜单
"*****主菜单*******\n",
"*****1增加*****\n",
"*****2删除*****\n",
"*****3修改*****\n",
"*****4查询*****\n",
"*****0退出*********\n",
"******************\n"};

char *menu_Query[]={
 "***查询主菜单*****\n",
 "**1按姓名查询*****\n",
 "**2按手机号查询***\n",
 "**3按姓名排序输出*\n",
 "**0返回主菜单*****\n",
 "******************\n"};

char *menu_Modify[]={
 "***修改主菜单******\n",
 "***1按姓名修改*****\n",
 "***2按手机号查询***\n",
 "***3按姓名排序输出*\n",
 "***0返回主菜单*****\n",
 "*******************\n"};


char *menu_Delete[]={
 "***删除主菜单****\n",
 "****1按姓名删除***\n",
 "****2按手机号删除*\n",
 "****3全部删除*****\n",
 "****0返回主菜单***\n",
 "******************\n"};


char menu(char *str[],int len)         //菜单打印与选择函数
{
 int i;
 char sel;
 for(i=0;i<len;i++)
 {
  printf("%s",str[i]);
 }
 printf("请输入您的选择:");
 scanf(" %c",&sel);
 getchar();
 return sel;
}

Status Initlist(llist *L)             //新建链表
{
 *L=(llist)malloc(sizeof(Node));
 if(*L==NULL)
 {
  printf("内存分配失败,按任意键退出...");
  getchar();
  exit(0);
 }
 else
 {
  (*L)->next=NULL;
  return TRUE;
 }
}

Status listLength(llist L)     //计算链表长度
{
 int i=0;
 llist p;
 p=L->next;
 while(p)
 {
  p=p->next;
  i++;
 }
 return i;
}

  Status listClear(llist *L)   //清空链表
{
 if(listLength(*L)==0)
 {
  printf("All Clear!");
  return TRUE;
 }
 int i=0;
 llist p,q;
 p=q=(*L)->next;
 while(p)
 {
  p=p->next;
  free(q);
  i++;
  q=p;
 }	
 (*L)->next = NULL;
 printf("clear item =%d\n",i);
 return TRUE;
}

 
Status Input(DataType *e)          //创建新的联系人信息
{
 int age;
 printf("请输入姓名  :");
 fgets(e->name,10,stdin);
 printf("请输入地址  :");
 fgets(e->addr,30,stdin);
 printf("请输入电话号码  :");
 fgets(e->tel,12,stdin);
 printf("请输入手机号码  :");
 fgets(e->mphone,12,stdin);
 printf("请输入性别  :");
 scanf(" %c",&(e->sex));
 getchar();
 printf("请输入年龄  :");
 scanf("%d",&age);
 getchar();
 e->age=(unsigned char)age;
 return TRUE;
}

Status Output(DataType e)   //将联系人信息输出
{
 char sex[3];
 printf("姓名:%s",e.name);
 printf("地址:%s",e.addr);
 printf("电话号码:%s",e.tel);
 printf("手机号码:%s",e.mphone);
 if('0'==e.sex)
 {
  strcpy(sex,"女");
 }
 else if('1'==e.sex)
 {
  strcpy(sex,"男");
 }
 else 
 {
 strcpy(sex,"错误");
 }
 printf("性别:%s\n",sex);
 printf("年龄:%d\n",(int)e.age);
 return TRUE;
 }

Status GetElem (llist L,int i,DataType *e)  //获取链表第i个位置信息
{
 int j=1;
 llist p;
 p=L;
 if(i<1||i>listLength(L))
 {
  return FALSE;
 }
 while( p && j<i)
 {
   p=p->next;
   ++j; 
 }
p=p->next;
*e=p->data;
return TRUE;
 }


Status Rfile(llist *L)            //读文件操作
{
 int i,size;
 DataType e;
 FILE *fp;             //定义文件流指针
 if((fp=fopen(fname,"r"))==NULL)     //打开文件
 {
  perror("打开文件失败");
  return FALSE;
 }
 fseek(fp,0,SEEK_END);          //将指针移到文件最后
 size=ftell(fp)/sizeof(DataType);  //计算文件大小
 rewind(fp);                    //将指针移到开头
 for(i=0;i<size;i++)        
 {
  fread(&e,sizeof(DataType),1,fp);  //从fp处,每次读一个数据
  listInsert(L,1,e);              //再插入链表中
 } 
 fclose(fp);                  //关闭文件
 return TRUE;
 }


Status Wfile(llist *L)           //将数据写入文件
{
 FILE *fp;                    
 int i;
 DataType e;
 if((fp=fopen(fname,"w"))==NULL)           //打开文件
 {
  perror("打开文件失败");
  return FALSE;
 }
 llist p;
 p=(*L)->next;
 while(p!=NULL)
   {
    e=p->data;
	fwrite(&e,sizeof(DataType),1,fp);        //从fp处每次写一个文件
	p=p->next;
   }
 fclose(fp);              //关闭文件
 return TRUE;
}


Status listInsert(llist *L,int i,DataType e)          //链表i位置插入一个新节点
{
 int j=1;
 llist p,s;
 if(i<1||i>listLength(*L)+1)            
 {
  return FALSE;
 }
 p=(*L);
 while(p && j<i)
 {
  p=p->next;
  j++;
 }
 s=(llist)malloc(sizeof(Node));        //分配新节点内存
 if (s==NULL)
  {
   printf("内存分配失败,按任意键退出...");
   getchar();
   exit(0);
  }
 s->data=e;
 s->next=p->next;
 p->next=s;
 return TRUE;
}

Status listDelete(llist *L,int i,DataType *e)   //删除第i个节点
{
 int j=1;
 llist p,s;
 if(i<1 || i>listLength(*L))
 {
  return FALSE;
 }
 p=*L;
 while(p && j<i)
 {
  p=p->next;
  j++;
 }
 s=p->next;
 *e=s->data;
 p->next=s->next;
 free(s);
 return TRUE;
}

Status listLocate(llist L,char *str,int flag)      //根据输入的信息查找在链表的位置i
{
 llist p;
 p=L->next;
 int i;
 if(L->next==NULL)
 {
  return -1;
 }

 switch(flag)
 {
  case 1:{
         i=1;
         while(p!=NULL)
        {
         if(!strcmp(str,p->data.name))
          {
		  return i;
		  }
		 else
		  {
		  p=p->next;
		  i++;
		  } 
		}
		return -1;
		} break;
 case 2:{
         i=1;
         while(p!=NULL)
         {
         if(!strcmp(str,p->data.mphone))
         {
		  return i;
		 }
		 else
		 {
		  p=p->next;
		  i++;
		 }
		}
       return -1;
	   } break;
 default: return -1;break;
 }}


void listSort(llist L)            //根据姓名首字母进行排序
{
 llist p,q;
 DataType temp;
 for(p=L->next;p!=NULL;p=p->next)
 {
   for(q=p->next;q!=NULL;q=q->next)
    {  if (strcmp(p->data.name,q->data.name)>0)
      {
	   temp=p->data;
       p->data=q->data;
       q->data=temp;
      }
     }
    }
} 
Status Query(llist L)           //查询功能
{
 int i,j;
 DataType e;
 llist p;
 char sel=1;
 char name[10],mphone[12];
 listSort(L);                      //先进行排序
 while('0'!=sel)
 {
   sel=menu(menu_Query,6);
   switch(sel)
   {
    case '0': break;
	case '1':{
	      printf("Please enter name:");        //按姓名查询
	      fgets(name,10,stdin);
	      j=listLocate(L,name,1);                //找到链表位置i
		  printf("j=%d",j);
          if(j!=(-1))
		    {
		     GetElem(L,j,&e);                //获得第i个元素
		     printf("The %d item is:\n",j);  
		     Output(e);                        //打印出来
			 getchar();
	        }
		  else
		  {
		    printf("No query1 record");
		    getchar();
		  }	
		    }break;
    case '2':{
	      printf("Please enter mphone:");
	      fgets(mphone,12,stdin);
		  j=listLocate(L,mphone,2);
          if(j!=(-1))
		    {
		     GetElem(L,j,&e);
		     printf("The %d item is:\n",j);
		     Output(e);
	        }
		  else
		  {
		    printf("No query record,press any key to continue...");
		    getchar();
		  }
		    }break;
	case '3':{
	         p=L->next; 
	         if(p==NULL)
		     {
			   printf("No query record,press any key to continue...");
			   getchar();
             }
	         for(j=1;j<listLength(L)+1;j++)                    //全部输出
               {
			     printf("The %d item is :\n",j);    
                 Output(p->data);
                 p=p->next;
               }
			   printf("Press any key to continue...");
			   getchar();
            }break;
	default:printf("Wrong sel ");break;
      }
    }
	return TRUE;
}

Status Delete(llist *L)         //删除功能,即先查找,再删除链表节点 
{
 int j;
 char sel=1,ch,name[10],mphone[12];
 DataType e;
 while(sel!='0')
 {
  sel=menu(menu_Delete,6);
  switch(sel)
  {
   case '0':break;
   case '1':{ 
             printf("Please enter name:\n");
			 fgets(name,10,stdin);
             j=listLocate(*L,name,1);
             if(j!=(-1))
			  {
			  GetElem(*L,j,&e);
              Output(e);
			  listDelete(L,j,&e);
              printf("Deleted!Press any key to continue...\n");
			  getchar();
			  } 
		     else
		     {
		       printf("No query record,press any key to continue...");
		       getchar();
		     }
			 }break;
   case '2':{
             printf("Please enter mphone:\n");
			 fgets(mphone,12,stdin);
             j=listLocate(*L,mphone,2);
             if(j!=(-1))
			  {
			  GetElem(*L,j,&e);
              Output(e);
			  listDelete(L,j,&e);
              printf("Deleted! Press any key to continue...");
			  getchar();
			  }
		      else
		      {
		        printf("No query record,press any key to continue...");
		        getchar();
		      }
			  }break; 
   case '3':{
			    printf("Are you sure? y/n");
                scanf("%c",&ch);
			    if('y'==ch)
			     {
			       listClear(L);
				   printf("All deleted!\n");
			     }
			 }break;
   default:printf("Wrong sel!\n");break;
   }
 }
   return TRUE;
}

Status Modify(llist *L)            //修改功能,即先查找,再删除,再插入
{
 int j;
 llist p;
 char sel=1,ch,name[10],mphone[12];
 DataType e;
 while(sel!='0')
 {
  sel=menu(menu_Modify,6);
  switch(sel)
  {
   case '0':break;
   case '1':{ 
             printf("Please enter name:\n");
			 fgets(name,10,stdin);
             j=listLocate(*L,name,1);
             if(j!=(-1))
			  {
			  GetElem(*L,j,&e);
              Output(e);
			  listDelete(L,j,&e);
			  Input(&e);
			  listInsert(L,j,e);
              printf("Modified!Press any key to continue...\n");
			  getchar();
			  } 
		     else
		     {
		       printf("No query record,press any key to continue...");
		       getchar();
		     }
			 }break;
   case '2':{
             printf("Please enter mphone:\n");
			 fgets(mphone,12,stdin);
             j=listLocate(*L,mphone,2);
             if(j!=(-1))
			  {
			  GetElem(*L,j,&e);
              Output(e);
			  listDelete(L,j,&e);
			  Input(&e);
			  listInsert(L,j,e);
              printf("Modified! Press any key to continue...");
			  getchar();
			  }
		      else
		      {
		        printf("No query record,press any key to continue...");
		        getchar();
		      }
			  }break; 
	case '3':{
	         p=(*L)->next; 
	         if(p==NULL)
		     {
			   printf("No query record,press any key to continue...");
			   getchar();
             }
	         for(j=1;j<listLength(*L)+1;j++)
               {
			     printf("The %d item is :\n",j);    
                 Output(p->data);
                 p=p->next;
               }
			   printf("Press any key to continue...");
			   getchar();
            }break;
   default:printf("Wrong sel!\n");break;
   }
 }
   return TRUE;
}
int main(int argc,char *argv[])
{
 DataType e;
 llist txl;
 char sel;
 Status flag;
 flag=Initlist(&txl);
 if(!flag)
 {
  printf("内存分配失败,按任意键退出...");
  getchar();
  exit(0);
 }
 if(!Rfile(&txl))                 //打开文件
 {
  printf("打开文件失败,按任意键退出...");
  getchar();
  exit(1);
 }
 while(1)
 {
  sel=menu(mainmenu,7);
  switch (sel)
   {
    case '1':memset(&e,0,sizeof(DataType));Input(&e);listInsert(&txl,1,e);break;     //增加联系人,先初始化e元素,再输入再插入
    case '2':Delete(&txl);break;
    case '3':Modify(&txl);break;
    case '4':Query(txl);break;
    case '0':printf("谢谢使用本软件,按任意键退出...");Wfile(&txl);getchar();exit(0);break;   //退出时将信息写入文件
    default:printf("错误输入");
   } 
 }
	return 0;
}
还是有很多需要优化的地方,例如重名问题啊什么的,但是该有的功能都有,程序运行也没问题,由于时间问题也就不继续优化修改了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值