通讯录

#include <stdio.h>
#include <string.h> 
#include <conio.h>
#include <string>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;

typedef struct Node
{
	char id[100];  //学号 
	char name[100]; //姓名 
	char tel[100]; //电话号码 
	struct Node *next;
}LinkList;

int total; // 通讯录的人数 

void Menu(LinkList * &L);
void AddRecords(LinkList * &L);    //通过键盘输入信息,添加一条通讯录记录 
void DeleteRecords(LinkList * &L); //通过键盘输入学号,删除该学号的记录 
void OutoutRecords(LinkList *L); //输出通讯录全部记录 
void FindName(LinkList *L);      //通过键盘输入姓名,输出该同学的所有信息 
void SaveRecords(LinkList *L);   //把通讯录中所有的记录保存到文件中 
void EmptyRecords(LinkList * &L);  //删除通讯录中的全部记录,并删除文件
void ReadFile(LinkList * &L);      //读取记录 
bool JudgeFile();     //判断文件是否存在 
void CreatNewFile();  //创建新的文件 
void InitList(LinkList * &L); //初始化单链表 
void Exit(); //退出系统 

int main()
{
	total = 0; //通讯录人数 
	LinkList *L = NULL;  
	if(!JudgeFile()) //判断文件是否存在 
		CreatNewFile();  //创建一个新的文件 
	InitList(L); //初始化单链表 
	ReadFile(L); //读取文件 
	Menu(L); // 主菜单 
	return 0;
}

void Menu(LinkList * &L)
{
	printf("\n\n\t\t\t\t通讯录管理系统\n\n");
	printf("\t\t\t\t\t\t\t当前通讯录人数:%d\n",total);
	printf("\t\t\t\t 1.添加记录\n\n"); 
	printf("\t\t\t\t 2.删除记录\n\n");
	printf("\t\t\t\t 3.输出记录\n\n");
	printf("\t\t\t\t 4.按姓名查找\n\n");
	printf("\t\t\t\t 5.保存记录\n\n");
	printf("\t\t\t\t 6.清空记录\n\n");
	printf("\t\t\t\t 7.退出系统\n\n"); 
	printf("请输入选择(1-7):");
	int choice;
	while(scanf("%d", &choice)) // 保证输入的要是1到7之间的数才进行下一步 
	{
		if(choice < 1 || choice > 7)
			printf("输入不正确,请重新输入:");
		else 
			break;
	}
	switch(choice)
	{
		case 1:
			system("cls"); // 清屏 
			AddRecords(L); // 添加记录 
			break;
		case 2:
			system("cls");
			DeleteRecords(L); // 删除记录 
			break;
		case 3:
			system("cls");
			OutoutRecords(L); // 输出记录 
			break;	
		case 4:
			system("cls");
			FindName(L); // 按姓名查找 
			break;
		case 5:
			system("cls");
			SaveRecords(L); // 保存记录 
			break;
		case 6:
			system("cls");
			EmptyRecords(L); // 清空记录 
			break;
		case 7:
			system("cls");
			Exit(); // 退出系统 
			break;
	}
}

void InitList(LinkList * &L) //初始化单链表 
{
	L = (LinkList *)malloc(sizeof(LinkList));  // 内存的自动分配 
	L->next = NULL; // 头结点的下一个节点为空 
}

void CreatNewFile() // 创建新文件 
{
	FILE * fp; // 文件指针 
	fp = fopen("tel.txt", "w"); // 打开文件,文件未存在时,新建文件 
	fclose(fp); // 关闭文件 
}

bool JudgeFile() // 判断文件是否存在 
{
	FILE *fp;
	fp = fopen("tel.txt", "r"); // 以只读的方式打开文件 
	if(fp == NULL)
	{
		return false;
	}
	else
	{
		fclose(fp);
		return true;
	}
}

void ReadFile(LinkList * &L) // 读取文件记录 
{
	FILE *fp;
	fp = fopen("tel.txt", "r"); // 以只读的方式打开文件 
	LinkList *p = L, *s;
	if(fgetc(fp) != NULL) // 判断文件中的第一个字符是否为空,并且光标自动下移一格 
	while(!feof(fp))//循环到文件末 
	{
		s = (LinkList *)malloc(sizeof(LinkList));
		fscanf(fp,"%s %s %s",&s->id,s->name,s->tel); // 读取文件内容到单链表中 
		p->next = s;
		p = s;
		s->next = NULL; //  将读取到的内容插入到单链表的末尾 
		total++; // 通讯录人数加1 
	}
	fclose(fp);
}

void AddRecords(LinkList * &L) // 添加记录 
{
	LinkList *p = L, *s;
	while(p->next != NULL) // 循环到下一个节点为空 ,即p为尾节点 
	{
		p = p->next;
	}
	s = (LinkList *)malloc(sizeof(LinkList));
	printf("请输入学号:");
	scanf("%s", s->id);
	printf("请输入姓名:");
	scanf("%s", s->name);
	printf("请输入电话号码:");
	scanf("%s", s->tel);
	p->next = s;
	s->next = NULL; // 插入到单链表尾部 
	printf("添加记录成功,是否继续添加(y/n):");
	total++;
	char x[20];
	scanf("%s", x);
	while(1)  
	{
		if(strcmp(x, "y") && strcmp(x, "n")) // 输入除了y和n这两个字符外时需重新输入 
		{
			printf("输入有误,请重新输入(y/n):"); 
			scanf("%s", x);
			continue;
		}
		else if(!strcmp(x, "y"))// 继续添加记录 
		{
			system("cls");
			AddRecords(L); 
		}
		else if(!strcmp(x, "n"))//返回至主菜单 
		{
			printf("系统即将返回至主菜单");
			_sleep(1000);//时间函数 ,用于执行下一条语句时,时间间隔为1000ms 
			printf(".");
			_sleep(1000);
			printf(".");
			_sleep(1000);
			printf(".\n");
			system("cls");
			break;
		}
	}
	Menu(L);
}

void DeleteRecords(LinkList * &L) // 删除记录 
{
	LinkList *p = L, *s;
	printf("请输入你要删除记录的学号:");
	s = (LinkList *)malloc(sizeof(LinkList));
	scanf("%s", s->id); 
	while(p->next != NULL && strcmp(p->next->id, s->id)) // 寻找到与id想匹配的节点 
	{
		p = p->next;
	} 
	free(s); 
	if(p->next == NULL)
	{
		printf("该记录不存在!\n");
	}
	else
	{
		p->next = p->next->next; // p的下一个节点为p的下一个的下一个的节点 
		printf("删除该记录成功!\n");
		total--; // 通讯录人数减1 
	} 
	_sleep(300);
	printf("是否继续删除?(y/n):");
	char c[10];
	while(scanf("%s",c))
	{
		if(strcmp(c,"y") && strcmp(c,"n"))
		{
			printf("输入错误,请重新输入:");
		}
		else
		{
			break;
		}
	}
	if(!strcmp(c,"y")) //继续删除记录 
	{
		system("cls");
		DeleteRecords(L); 
	}
	else
	{
		printf("即将返回至主菜单");
		_sleep(1000);
		printf("."); 
		_sleep(1000);
		printf(".");
		_sleep(1000);
		printf(".\n");
		system("cls");
		Menu(L);
	}
} 

void OutoutRecords(LinkList *L)  // 输出记录 
{
	LinkList *p = L->next;
	printf("学号\t\t姓名\t\t电话号码\n");
	while(p != NULL) // 从头结点的下一个节点开始循环到节点为NULL 
	{
		_sleep(300);
		printf("%-16s%-16s%-16s\n",p->id,p->name,p->tel);
		p = p->next;
	}
	_sleep(300); 
	printf("\n\n是否返回主菜单?(1.返回主菜单 2.退出系统) : ");
	int choice;
	while(scanf("%d", &choice))
	{
		if(choice < 1 || choice > 2)
			printf("输入不正确,请重新输入:");
		else 
			break;
	}
	if(choice == 1)
	{
		system("cls");
		Menu(L);
	}
	else if(choice == 2)
	{
		system("cls");
		Exit();
	}
}

void FindName(LinkList *L) // 按姓名查找 
{
	LinkList *p = L->next, *s;
	printf("请输入要查找的姓名:");
	s = (LinkList *)malloc(sizeof(LinkList));
	scanf("%s", s->name); 
	while(p != NULL && strcmp(p->name, s->name)) // 寻找与name匹配的节点 
	{
		p = p->next;
	}
	free(s);
	if(p == NULL)
	{
		printf("该记录不存在!\n");
	} 
	else
	{
		system("cls");
		printf("学号:%s\n姓名:%s\n电话号码:%s\n", p->id, p->name, p->tel);
	}
	_sleep(300);
	printf("是否继续查找?(y/n):");
	char c[10];
	while(scanf("%s",c))
	{
		if(strcmp(c,"y") && strcmp(c,"n"))
		{
			printf("输入错误,请重新输入:");
		}
		else
		{
			break;
		}
	}
	if(!strcmp(c,"y"))
	{
		system("cls");
		FindName(L);
	}
	else
	{
		printf("即将返回至主菜单");
		_sleep(1000);
		printf("."); 
		_sleep(1000);
		printf(".");
		_sleep(1000);
		printf(".\n");
		system("cls");
		Menu(L);
	}
}

void SaveRecords(LinkList * L) // 保存记录 
{
	FILE * fp;
	fp = fopen("tel.txt", "w"); // 以写入文件的方式打开文件 
	LinkList *p = L->next; // p指向L节点的下一个节点 
	if(p != NULL) 
	while(p != NULL) 
	{
		if(p->next == NULL) // 使用判断来写入,主要是为了使得写入后的文件末不在下一行,否则会因为这一空行而出现乱码 
			fprintf(fp," %s %s %s",p->id,p->name,p->tel);
		else
			fprintf(fp," %s %s %s\n",p->id,p->name,p->tel);
		p = p->next;
	}
	fclose(fp);
	printf("文件保存成功!即将返回主菜单");
	_sleep(1000);
	printf("."); 
	_sleep(1000);
	printf(".");
	_sleep(1000);
	printf(".\n");
	system("cls");
	Menu(L);
}

void EmptyRecords(LinkList *&L) //清空记录 
{
	FILE * fp;
	fp = fopen("tel.txt","w"); // 以文件写入的方式打开文件,然后再关闭,相当于重新创建了一个新的文件。 
	fclose(fp);
	InitList(L);//初始化单链表,要是清空记录,那么,单链表要变为空,那么初始化一下即可 
	printf("文件记录已清空,3秒后返回至主菜单");
	_sleep(1000);
	printf("."); 
	_sleep(1000);
	printf(".");
	_sleep(1000);
	printf(".\n");
	system("cls");
	Menu(L);
}

void Exit() // 退出系统 
{
	printf("\n\n\n\t\t系统将在3秒后关闭");
	_sleep(1000);
	printf(".");
	_sleep(1000);
	printf(".");
	_sleep(1000);
	printf(".\n");	
	exit(0);	 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值