/*****************************************************************
* 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;
}
还是有很多需要优化的地方,例如重名问题啊什么的,但是该有的功能都有,程序运行也没问题,由于时间问题也就不继续优化修改了
C语言小功能实现--通讯录功能
最新推荐文章于 2022-03-08 19:13:29 发布