通讯录

@第一个练手程序

欢迎阅读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;
	}
}

对其中的一些知识点也不是很懂,如果你想了解更多,关注我,我们一起学习

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值