欢迎阅读code guitar(小猿也爱吉他:简称 猿吉)的小程序
用C语言写一个手机通讯录
功能实现:增(添加信息)删(删除信息)查(查询信息,支持前缀模糊查询)改(修改信息)
概要:全过程以一链表为主体,对该链表进行一系列功能实现
所需掌握知识:链表的基本功能(链表的添加、链表的删除)
结构体
switch()语句的运用
全局变量
静态变量
函数的灵活运用
动态申请空间即堆区申请空间(malloc函数)
。。。。。。。。
为了方便调试 所以初始化了100条信息
在这里插入代码片
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
typedef struct NODE
{
int id;
char*name;
char*tel;
struct NODE*pNext;
}Node;
typedef struct PAGE
{
int Currentpage;
int Totalpage;
int TotalInfo;
int OnepageInfo;
}Page;
int g_Menu;
char g_key;
Node*GetNode();
int Getid();
char*Getname();
char*Gettel();
void AddNode(Node**ppHead,Node**ppEnd,Node*pNode);
void InitInfo(Node**ppHead,Node**ppEnd,int n);
Page*Getpage(Node*pHead,int n);
void showInfo(Node*pHead,Page*pPage);
void showMenu(Page*pPage);
void Turnpage(Node*pHead,Page*pPage);
char Getkey();
void Browse(Node*pHead);
Node* GetNodeIn();
char* Getstring();
void Query(Node*pHead);
void DeleNode(Node**ppHead,Node**ppEnd,int id);
void DeleInfo(Node**ppHead,Node**ppEnd);
void UpdateInfo(Node*pHead);
int main()
{
Node* pHead = NULL;
Node* pEnd = NULL;
char c;
InitInfo(&pHead,&pEnd,100);
while(1)
{
printf("1.查看通讯录\n");
printf("2.添加信息\n");
printf("3.查询信息\n");
printf("4.删除信息\n");
printf("5.修改信息\n");
printf("q。退出\n");
switch(c = Getkey())
{
case '1':
g_Menu = 1;
Browse(pHead);
break;
case '2':
AddNode(&pHead,&pEnd,GetNodeIn());
break;
case '3':
g_Menu = 3;
Query(pHead);
break;
case '4':
g_Menu = 4;
DeleInfo(&pHead,&pEnd);
break;
case '5':
g_Menu = 5;
UpdateInfo(pHead);
break;
case 'q':
return 0;
break;
}
}
return 0;
}
Node*GetNode()
{
Node*pNode = (Node*)malloc(sizeof(Node));
pNode->id =Getid();
pNode->name =Getname();
pNode->tel = Gettel();
pNode->pNext=NULL;
return pNode;
}
void AddNode(Node**ppHead,Node**ppEnd,Node*pNode)
{
if(*ppHead == NULL)
{
*ppHead = pNode;
}
else
{
(*ppEnd)->pNext = pNode;
}
*ppEnd = pNode;
}
int Getid()
{
static int id=1;
return id++;
}
char*Getname()
{
int i;
char*pName = (char*)malloc(6);
for(i=0;i<5;i++)
{
pName[i] = rand()%26 + 'a';
}
pName[i] = '\0';
return pName;
}
char*Gettel()
{
char*pTel = (char*)malloc(12);
int i;
switch(rand()%4)
{
case 0:
strcpy_s(pTel,12,"188");
break;
case 1:
strcpy_s(pTel,12,"177");
break;
case 2:
strcpy_s(pTel,12,"155");
break;
case 3:
strcpy_s(pTel,12,"133");
break;
}
for(i=3;i<11;i++)
{
pTel[i] = rand()%10 + '0';
}
pTel[i] = '\0';
return pTel;
}
void InitInfo(Node**pHead,Node**pEnd,int n)
{
int i;
for(i=0;i<n;i++)
{
AddNode(pHead,pEnd,GetNode());
}
}
Page*Getpage(Node*pHead,int n)
{
Page*pPage = (Page*)malloc(sizeof(Page));
pPage->Currentpage = 0;
pPage->OnepageInfo = n;
pPage->TotalInfo = 0;
pPage->Totalpage = 0;
while(pHead != NULL)
{
pPage->TotalInfo++;
pHead = pHead->pNext;
}
if(pPage->TotalInfo % pPage->OnepageInfo == 0)
{
pPage->Totalpage = pPage->TotalInfo / pPage->OnepageInfo ;
}
else
{
pPage->Totalpage = pPage->TotalInfo / pPage->OnepageInfo + 1;
}
return pPage;
}
void showInfo(Node*pHead,Page*pPage)
{
int count=0;
int begin = ( pPage->Currentpage - 1)*pPage->OnepageInfo +1;
int end = pPage->Currentpage * pPage->OnepageInfo ;
while(pHead != NULL)
{
count ++;
if(begin <= count && count <= end )
{
printf("%d\t%s\t%s\n",pHead->id,pHead->name,pHead->tel);
}
pHead = pHead ->pNext;
}
}
void showMenu(Page*pPage)
{
switch(g_Menu)
{
case 1:
printf("当前第%d页 共%d页 共%d条 s下一页 w上一页 b返回\n",pPage->Currentpage,pPage->Totalpage,pPage->TotalInfo);
break;
case 3:
printf("当前第%d页 共%d页 共%d条 s下一页 w上一页 c重新查询 b返回\n",pPage->Currentpage,pPage->Totalpage,pPage->TotalInfo);
break;
case 4:
printf("当前第%d页 共%d页 共%d条 s下一页 w上一页 d删除信息 b返回\n",pPage->Currentpage,pPage->Totalpage,pPage->TotalInfo);
break;
case 5:
printf("当前第%d页 共%d页 共%d条 s下一页 w上一页 u修改信息 b返回\n",pPage->Currentpage,pPage->Totalpage,pPage->TotalInfo);
break;
}
}
void Turnpage(Node*pHead,Page*pPage)
{
char c ='s';
while(1)
{
switch(c)
{
case 's':
if(pPage->Currentpage >= pPage->Totalpage)
{
printf("已经到最后一页了\n");
}
else
{
pPage->Currentpage++;
showInfo(pHead,pPage);
showMenu(pPage);
}
break;
case 'w':
if(pPage->Currentpage <= 1)
{
printf("已经到第一页了\n");
}
else
{
pPage->Currentpage--;
showInfo(pHead,pPage);
showMenu(pPage);
}
break;
case 'b':
return ;
break;
case 'c':
return;
break;
case 'd':
return ;
break;
case 'u':
return;
break;
default:
printf("摁错了\n");
break;
}
c = Getkey();
g_key = c;
}
}
char Getkey()
{
char c;
char z;
int flag =1;
while((c = getchar()) != '\n'||flag==1)
{
z=c;
flag =0;
}
return z;
}
void Browse(Node*pHead)
{
Page*pPage = NULL;
pPage = Getpage(pHead,10);
Turnpage(pHead,pPage);
}
Node*GetNodeIn()
{
Node*pNode = (Node*)malloc(sizeof(Node));
pNode->id =Getid();
printf("请输入姓名:\n");
pNode->name =Getstring();
printf("请输入电话:\n");
pNode->tel = Getstring();
pNode->pNext=NULL;
return pNode;
}
char*Getstring()
{
int size=5;
int count =0;
char c;
char*str1 = (char*)malloc(size);
char*pMark = str1;
char*newstr = NULL;
while((c=getchar()) != '\n')
{
*str1 = c;
str1++;
count++;
if(count +1 == size)
{
size+=5;
*str1 = '\0';
newstr = (char*)malloc(size);
strcpy_s(newstr,size,pMark);
free(pMark);
pMark = newstr;
str1 = newstr + count ;
}
}
*str1 = '\0';
return pMark;
}
void Query(Node*pHead)
{
char*keyword = NULL;
Node*pNewHead = NULL;
Node*pNewEnd = NULL;
Node*pDel = NULL;
Node*pMark = pHead;
while(1)
{
while(1)
{
printf("请输入关键字:\n");
keyword = Getstring();
printf("a确认 其他键返回\n");
if('a'== Getkey())
{
break;
}
else
{
free(keyword);
keyword = NULL;
}
}
pMark = pHead;
while(pHead != NULL)
{
if(strncmp(pHead->name,keyword,strlen(keyword)) == 0||strncmp(pHead->tel,keyword,strlen(keyword))==0)
{
Node*pNewNode = (Node*)malloc(sizeof(Node));
pNewNode->id = pHead->id;
pNewNode->name = pHead->name;
pNewNode->tel = pHead->tel;
pNewNode->pNext = NULL;
AddNode(&pNewHead,&pNewEnd,pNewNode);
}
pHead = pHead ->pNext;
}
Browse(pNewHead);
while(pNewHead != NULL)
{
pDel = pNewHead;
pNewHead = pNewHead->pNext;
free(pDel);
pDel = NULL;
}
pNewEnd = NULL;
if('b'==g_key||'d'==g_key||'u'==g_key)
{
break;
}
}
}
void DeleNode(Node**ppHead,Node**ppEnd,int id)
{
Node*pMark = *ppHead;
Node*pDel = NULL;
if((*ppHead)->id == id)
{
pDel = *ppHead;
*ppHead = (*ppHead)->pNext;
free(pDel->name);
free(pDel->tel);
free(pDel);
return;
}
while(pMark->pNext != NULL)
{
if(pMark->pNext->id == id)
{
pDel = pMark->pNext;
pMark->pNext = pMark->pNext->pNext;
free(pDel->name);
free(pDel->tel);
free(pDel);
pDel = NULL;
if(pMark->pNext== NULL)
{
*ppEnd = pMark;
}
return ;
}
pMark = pMark->pNext;
}
}
void DeleInfo(Node**ppHead,Node**ppEnd)
{
int id;
char*pId = NULL;
while(1)
{
Query(*ppHead);
if('b'==g_key)
{
return;
}
printf("请输入要删除的编号:\n");
pId = Getstring();
id = atoi(pId);
free(pId);
pId = NULL;
DeleNode(ppHead,ppEnd,id);
printf("是否继续 Y继续删除 其他键返回\n");
if(Getkey() != 'y')
{
break;
}
}
}
void UpdateInfo(Node*pHead)
{
int id;
char*pId = NULL;
char*pStr = NULL;
Query(pHead);
printf("请输入修改编号:\n");
pId = Getstring();
id = atoi(pId);
free(pId);
pId = NULL;
//这里为何还需遍历链表呢?
//查询分页显示后需要遍历一遍链表找到需要修改的编号
while(pHead != NULL)
{
if(pHead->id == id)
{
printf("请输入姓名:\n");
pStr = Getstring();
if(strlen(pStr)>0)
{
free(pHead->name);
pHead->name = pStr;
}
printf("请输入电话:\n");
pStr = Getstring();
if(strlen(pStr)>0)
{
free(pHead->tel);
pHead->tel = pStr;
}
}
pHead = pHead->pNext;
}
}
对其中的一些知识点也不是很懂,如果你想了解更多,关注我,我们一起学习