通讯录升级版(附带记事本功能+密码设置与解锁+原有的包括按需排序等的六大功能)

本人水平实在有限学的还少,这个东西已经花了我很长时间并且找了一遍又一遍的错误,但可能还有一些BUG,大家可以测试一下,谢谢! 

test.c 文件(测试通讯录) 

#define _CRT_SECURE_NO_WARNINGS 1


#include "contact.h"
#include "note.h"


void menu_contact(void)
{
	printf("************************************************\n");
	printf("********         My    Contact         *********\n");
	printf("********      1. add      2. del       *********\n");
	printf("********      3. search   4. show      *********\n");
	printf("********      5. modify   6. sort      *********\n");
	printf("********      7. note     0. exit      *********\n");
	printf("************************************************\n");
}


void menu_note(void)
{
	printf("************************************************\n");
	printf("********         My Daily Note         *********\n");
	printf("********      1. add      2. del       *********\n");
	printf("********      3. browse   0. exit      *********\n");
	printf("************************************************\n");
}


int main()
{
	int input_contact = 0;
	int input_note = 0;
	Contact Con;                  //创建通讯录结构体与结构体指针
	Contact* pc = &Con;
	Note book;				      //创建日记本结构体变量与指针
	Note* bookpoint = &book;   
	Init_Con(pc);                 //初始化通讯录结构体
	Init_book(bookpoint);         //初始化日记本结构体
	if (!PasswordSetting())                   //设置第一次登录通讯录的密码
	{
		printf("用户放弃设置密码,退出程序....\n");
		return 0;
	}
	system("cls");
	if (!PasswordAccess())                    //用户放弃输入密码
	{
		printf("访问通讯录失败....\n");
		return 0;
	}
	//正式进入通讯录里面
	do
	{
		system("cls");
		menu_contact();
		printf("--------     当前已有联系人:%d/%d        ---------\n", pc->sz, pc->capacity);
		printf("请输入菜单上的数字:");
		scanf("%d", &input_contact);
		printf("\n");
		switch (input_contact)
		{
		case 1:
			AddContact(pc);
			Sleep(2000);
			break;
		case 2:
			DelContact(pc);
			Sleep(2000);
			break;
		case 3:
			SearchContact(pc);
			HoldupDisplay();
			break;
		case 4:
			ShowContact(pc);
			HoldupDisplay();
			break;
		case 5:
			ModifyContact(pc);
			Sleep(2000);
			break;
		case 6:
			SortContact(pc);
			Sleep(2000);
			break;
		case 7:
			if (!PasswordAccess())
			{
				printf("无法访问记事本\n");
				break;
			}
			do
			{
				system("cls");
				menu_note();
				printf("--------      当前已有记事:%d/%d        ---------\n", bookpoint->sz, bookpoint->capacity);
				printf("请输入菜单上的数字:");
				scanf("%d", &input_note);
				printf("\n");
				switch (input_note)
				{
				case 1:
					AddNote(bookpoint);
					HoldupDisplay();
					break;
				case 2:
					DelNote(bookpoint);
					Sleep(2000);
					break;
				case 3:
					BrowseNote(bookpoint);
					HoldupDisplay();
					break;
				case 0:
					printf("退出成功,将返回通讯录\n");
					break;
				}
			} while (input_note);
			break;
		case 0:
			DestroyContact(pc);
			DestroyNote(bookpoint);
			printf("退出通讯录\n");
			break;
		default:
			printf("输入有误,重新输入\n");
			break;
		}
	} while (input_contact);
	return 0;
}

note.h 有关于记事本的头文件 

#pragma once


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>


#define Book_Capacity_Max 5
#define Book_Capacity_INC 5
#define Original_Words_Limit 10
#define Tmp_Note_Words 150


//日记本结构体
typedef struct Note
{
	char** message;
	int sz;
	int capacity;
}Note;                       //结构体类型为Note


//初始化日记结构体变量
void Init_book(bookpoint);


//检查你输入的字符个数与bookmark指向的堆区空间预先设置的字数的大小关系,条件满足进行加长
void CheckTmpNoteWords(int LenOfWords, int OriginalWordsLimit, char** Message);


//判断当前日记条数是否已满,已满则扩容
void CheckCapacity_Note(Note* bookpoint);


//增加一条记事
void AddNote(Note* bookpoint);


//浏览已有记事
void BrowseNote(const Note* bookpoint);


//删除指定的记事
void DelNote(Note* bookpoint);


//程序结束销毁通讯录
void DestroyNote(bookpoint);

note.c 有关于记事本功能实现的源文件 

#define _CRT_SECURE_NO_WARNINGS 1


#include "note.h"


//初始化结构体变量
void Init_book(Note* bookpoint)
{
	assert(bookpoint);
	bookpoint->message = (char**)malloc(Book_Capacity_Max * sizeof(char*));
	if (bookpoint->message == NULL)
	{
		perror("Init_book::Malloc");
		return;
	}
	bookpoint->capacity = Book_Capacity_Max;
	bookpoint->sz = 0;
}


//判断当前日记条数是否已满,已满则扩容
void CheckCapacity_Note(Note* bookpoint)
{
	assert(bookpoint);
	if (bookpoint->capacity == bookpoint->sz)
	{
		printf("日记条数已满,已将容量扩充%d条\n", Book_Capacity_INC);
		printf("\n");
		char* tmp = (char*)realloc(bookpoint->message, sizeof(char*) * (bookpoint->capacity + Book_Capacity_INC));  //扩容
		if (tmp == NULL)
		{
			perror("CheckCapacity_Note::Realloc");
			return;
		}
		bookpoint->message = tmp;
		bookpoint->capacity += Book_Capacity_INC;
	}
}


//检查你输入的字符个数与bookmark指向的堆区空间预先设置的字数的大小关系,条件满足进行加长
void CheckTmpNoteWords(int LenOfWords, int OriginalWordsLimit, char** Message)
{
	assert(Message);
	if (LenOfWords > OriginalWordsLimit)
	{
		char* tmp = (char*)realloc(*Message, sizeof(char) * LenOfWords + 1);     //  +1  是为了等会打印的时候撞见\0      
		if (tmp == NULL)
		{
			perror("CheckTmpNoteWords::Malloc");
			return;
		}
		*Message = tmp;
		printf("由于你的字数超出原有既定限制,现将空间自动扩容至%d字节\n", LenOfWords);
	}
}


//增加一条记事
void AddNote(Note* bookpoint)
{
	assert(bookpoint);
	CheckCapacity_Note(bookpoint);
	char* bookmark = (char*)malloc(Original_Words_Limit * sizeof(char));       //在message指向的堆区空间的每个元素记为bookmark
	if (bookmark == NULL)                                                      //bookmark又指向一块堆区空间
	{
		perror("AddNote::Malloc");
		return;
	}
	bookpoint->message[bookpoint->sz] = bookmark;
	char Input_words[Tmp_Note_Words] = { 0 };
	printf("请输入你要记录的内容:");
	getchar();                                                                //清理输入缓冲区
	gets(Input_words);
	int LenOfWords = strlen(Input_words);                                                             //我输入的字符个数                             
	CheckTmpNoteWords(LenOfWords, Original_Words_Limit, bookpoint->message + bookpoint->sz);          //必要时进行加长空间
	strcpy(bookpoint->message[bookpoint->sz], Input_words);                                           //拷贝字符串到堆区
	printf("\n");
	printf("添加成功!此次你添加的记事:%s\n", bookpoint->message[bookpoint->sz]);
	printf("\n");
	bookpoint->sz++;
}


//浏览已有记事
void BrowseNote(const Note* bookpoint)
{
	assert(bookpoint);
	if (bookpoint->sz == 0)
	{
		printf("当前无记录......\n");
		return;
	}
	printf("当前已有记事如下:\n");
	int i = 0;
	for (i = 0; i < bookpoint->sz; i++)
	{
		printf("%d:>  %s\n", i + 1, bookpoint->message[i]);
	}
}


//删除指定的记事
void DelNote(Note* bookpoint)
{
	BrowseNote(bookpoint);
	int num = 0;
	printf("请选择要删除的记事的序号:");
	scanf("%d", &num);
	if (num > bookpoint->sz)
	{
		printf("输入错误,当前最多仅有%d份记录\n", bookpoint->sz);
		return;
	}
	int i = 0;
	for (i = num - 1; i <= (bookpoint->sz) - 2; i++)
	{
		strcpy(bookpoint->message[i], bookpoint->message[i + 1]);
	}
	free(bookpoint->message[(bookpoint->sz) - 1]);
	bookpoint->sz--;
	char** tmp = (char**)realloc(bookpoint->message, sizeof(char*) * bookpoint->sz);
	if (tmp == NULL)
	{
		perror("DelNote::Realloc");
	}
	bookpoint->message = tmp;
	printf("删除成功\n");
}


//程序结束销毁记事本
void DestroyNote(Note* bookpoint)
{
	assert(bookpoint);
	int i = 0;
	for (i = 0; i < bookpoint->sz; i++)
	{
		free(bookpoint->message[i]);
	}
	free(bookpoint);
	bookpoint->message = NULL;
	bookpoint->capacity = 0;
	bookpoint->sz = 0;
	bookpoint = NULL;
}

contact.h 有关于通讯录(除记事本)的头文件 

#pragma once


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>


#define Password_MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 20
#define TELE_MAX 20
#define STANDARD_NUM 5
#define INC_SZ 3
#define CAP_MAX 5


//人员结构体
typedef struct PeoInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;


//通讯录结构体
typedef struct Contact
{
	PeoInfo* data;
	int capacity;
	int sz;
}Contact;


//密码
static char InputPassword_Final[Password_MAX] = { '\0' };


//滞留显示功能的函数(按0退出)
void HoldupDisplay(void);


//初始化通讯录结构体
void Init_Con(Contact* pc);


//判断用户设置的密码是否合规
int JudgePassword(char* InputPassword);


//设置通讯录密码
int PasswordSetting(void);


//执行操作前的密码输入
int PasswordAccess(void);


//判断通讯录是否需要增容
void CheckCapicity_Contact(Contact* pc);


//增加通讯录联系人
void AddContact(Contact* pc);


//输入姓名查找联系人
int FindByName(const Contact* pc, char* name);


//删除通讯录联系人
void DelContact(Contact* pc);


//查找指定联系人
void SearchContact(const Contact* pc);


//显示通讯录所有人的信息
void ShowContact(const Contact* pc);


//对于排序标准的界定
int CmpStandard(const char* standard);


//按照规则排序联系人
void SortContact(const Contact* pc);


//修改通讯录联系人
void ModifyContact(Contact* pc);


//程序结束销毁通讯录
void DestroyContact(Contact* pc);

contact.c 有关于通讯录功能实现的源文件 

#define _CRT_SECURE_NO_WARNINGS 1


#include "contact.h"
#include "note.h"


//滞留显示功能的函数(按0退出)
void HoldupDisplay()
{
	int num = 0;
	printf("..........\n");
	printf("按0退出:");
	while (1)
	{
		scanf("%d", &num);
		if (num == 0)
			break;
		printf("输入无效,重新输入:");
	}
}


//初始化通讯录结构体
void Init_Con(Contact* pc)
{
	assert(pc);
	pc->data = (PeoInfo*)calloc(CAP_MAX, sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("Init_Con::Calloc");
		return;
	}
	pc->sz = 0;
	pc->capacity = CAP_MAX;
}


//判断用户设置的密码是否合规
int JudgePassword(char* InputPassword)
{
	assert(InputPassword);
	int len = strlen(InputPassword);
	if (len < 6)
		return 0;
	int flag1 = 0;
	int flag2 = 0;
	int flag3 = 0;
	int i = 0;
	for (i = 0; i < len; i++)
	{
		if (islower(*(InputPassword + i)))
			flag1 = 1;
		else if (isupper(*(InputPassword + i)))
			flag2 = 1;
		else if (isdigit(*(InputPassword + i)))
			flag3 = 1;
		if (flag1 + flag2 + flag3 == 3)
			return 1;
	}
	return 0;
}


//设置通讯录的密码
int PasswordSetting()
{
	char InputPassword[Password_MAX] = { 0 };
Elon:
	printf("*******************       PASSWORD    SETTING       ******************* \n");
	printf("请设置通讯录密码(必须包含大小写字母与数字 && 长度不低于6个)(按0退出访问通讯录):");
	while (1)
	{
		gets(InputPassword);
		if (strcmp("0", InputPassword) == 0)
			return 0;
		if (JudgePassword(InputPassword))         //第一次输入已经成功,第二次输入确认
		{
			system("cls");
			while (1)
			{
				printf("请再次输入确认密码(按0重新设置):");
				gets(InputPassword_Final);
				if (strcmp("0", InputPassword_Final) == 0)
				{
					system("cls");
					goto Elon;
				}
				if (strcmp(InputPassword, InputPassword_Final) == 0)
				{
					printf("密码已经设置成功!\n");
					printf("正在加载.........\n");
					Sleep(2000);
					return 1;
				}
				else
					printf("输入有误,重新输入\n");
			}
		}
		else
			printf("设置的密码不合规范,请重新输入(按0退出访问通讯录):");
	}
}


//执行操作前的密码输入
int PasswordAccess(void)
{
	char password[Password_MAX] = { 0 };
	printf("请输入密码以解锁访问与修改权限(按0退出访问):");
	while (1)
	{
		gets(password);
		if (strcmp(password, "0") == 0)
			return 0;
		if (strcmp(password, InputPassword_Final) == 0)
		{
			printf("输入成功,正在加载.....\n");
			Sleep(1000);
			return 1;
		}
		else
		{
			printf("输入错误,请重新输入(按0退出访问):");
		}
	}
	return 0;
}


//判断通讯录是否需要增容
void CheckCapicity_Contact(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		printf("当然通讯录已满,容量将自动增加%d个\n", INC_SZ);
		PeoInfo* data_1 = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (data_1 == NULL)
		{
			perror("CheckCapacity::Realloc");
			return;
		}
		pc->data = data_1;
		pc->capacity += INC_SZ;
	}
}


//增加通讯录联系人
void AddContact(Contact* pc)
{
	assert(pc);
	CheckCapicity_Contact(pc);
	printf("请输入联系人姓名:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入联系人性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入联系人年龄:");
	scanf("%d", &pc->data[pc->sz].age);
	printf("请输入联系人地址:");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入联系人电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("输入成功,添加信息如下:\n");
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-15s\n", "NAME", "SEX", "AGE", "ADDRESS", "TELENUMBER");
	printf("%-20s\t%-5s\t%-5d\t%-20s\t%-15s\n", pc->data[pc->sz].name,
		pc->data[pc->sz].sex,
		pc->data[pc->sz].age,
		pc->data[pc->sz].addr,
		pc->data[pc->sz].tele);
	pc->sz++;
}


//输入姓名查找联系人
int FindByName(const Contact* pc, char* name)
{
	assert(pc && name);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			return i;
	}
	return -1;
}


//删除通讯录联系人
void DelContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入联系人姓名:");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	int i = 0;
	for (i = pos; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("已删除成功\n");
}


//查找指定联系人
void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入联系人姓名:");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("该联系人的信息为:\n");
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-15s\n", "NAME", "SEX", "AGE", "ADDRESS", "TELENUMBER");
	printf("%-20s\t%-5s\t%-5d\t%-20s\t%-15s\n", pc->data[pos].name,
		pc->data[pos].sex,
		pc->data[pos].age,
		pc->data[pos].addr,
		pc->data[pos].tele);
}


//显示通讯录所有人的信息
void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("当前所有联系人的信息为:\n");
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-15s\n", "NAME", "SEX", "AGE", "ADDRESS", "TELENUMBER");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-20s\t%-15s\n", pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}


//对于排序标准的界定
int CmpStandard(const char* StdNeed)
{
	assert(StdNeed);
	char* standard[STANDARD_NUM] = { "NAME","SEX","AGE","ADDRESS","TELENUMBER" };
	int sz = sizeof(standard) / sizeof(standard[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		if (strcmp(standard[i], StdNeed) == 0)
		{
			return i;
		}
	}
	return -1;
}


//qsort排序姓名
int cmp_name(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}


//qsort排序性别
int cmp_sex(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}


//qsort排序age
int cmp_age(const void* e1, const void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}


//qsort排序地址
int cmp_addr(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}


//qsort排序电话
int cmp_tele(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}


//按照规则排序联系人
void SortContact(const Contact* pc)
{
	assert(pc);
	char StdNeed[NAME_MAX] = { 0 };
	printf("请输入排序的标准(NAME/SEX/AGE/ADDRESS/TELENUMBER):");
	scanf("%s", StdNeed);
	int ret = CmpStandard(StdNeed);
	switch (ret)
	{
	case 0:
		qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);
		break;
	case 1:
		qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_sex);
		break;
	case 2:
		qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_age);
		break;
	case 3:
		qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_addr);
		break;
	case 4:
		qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_tele);
		break;
	}
	printf("已排序完成\n");
}


//修改通讯录联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改的联系人姓名:");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	printf("请输入新的联系人姓名:");
	scanf("%s", pc->data[pos].name);
	printf("请输入新的联系人性别:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入新的联系人年龄:");
	scanf("%d", &pc->data[pos].age);
	printf("请输入新的联系人地址:");
	scanf("%s", pc->data[pos].addr);
	printf("请输入新的联系人电话:");
	scanf("%s", pc->data[pos].tele);
	printf("已经修改成功\n");
}


//程序结束销毁通讯录
void DestroyContact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
	pc = NULL;
}

 

 

 

 

 

 

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

絕知此事要躬行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值