c语言通讯录——文件版本(带详细文字解释)

news2024/11/19 9:34:36

在这里插入图片描述

1.定义一个用于存储一个人的信息的结构体

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;

定义了一个名为 “PeoInfo” 的结构体(struct)类型,用于存储有关一个人的信息。
该结构体包含以下字段:

“name” - 一个字符数组,最多可以存储 NAME_MAX 个字符,表示这个人的姓名。
“age” - 一个整数,表示这个人的年龄。
“sex” - 一个字符数组,最多可以存储 SEX_MAX 个字符,表示这个人的性别。
“addr” - 一个字符数组,最多可以存储 ADDR_MAX 个字符,表示这个人的地址。
“tele” - 一个字符数组,最多可以存储 TELE_MAX 个字符,表示这个人的电话号码。

这个结构体可以用于存储一个人的信息,并且可以作为需要处理人员数据的函数的参数或返回类型。通常使用 typedef 创建结构体的别名,以允许更简洁的代码。

2.定义一个表示通讯录的结构体

typedef struct Contact
{
	PeoInfo* data;//指向存放人的信息的空间
	int sz;//当前已经放的信息的个数
	int capacity;//当前通讯录的最大容量
}Contact;

这段代码定义了一个名为 Contact 的结构体类型,用于表示通讯录。

该结构体包含三个成员变量:

PeoInfo* data:指向存放联系人信息的空间的指针,该空间由动态内存分配获得。
int sz:当前已经存储的联系人信息的个数。
int capacity:当前通讯录的最大容量,即可以存储的联系人信息的最大个数。
该结构体类型定义了通讯录的基本信息和存储方式,可以用于管理通讯录中的联系人信息。

3.创建主函数框架

int input;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case 1://添加联系人
			AddContact(&con);
			break;
		case 2://删除联系人
			DelContact(&con);
			break;
		case 3://查找联系人
			SearchContact(&con);
			break;
		case 4://更改联系人
			ModifyContact(&con);
			break;
		case 5://显示联系人
			ShowContact(&con);
			break;
		case 6://排序联系人
			SortContactName(&con);
			break;
		case 0:
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出通讯录");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);

这段代码是一个通讯录管理系统的主程序,用于调用各个函数实现添加、删除、查找、修改、显示、排序联系人信息等功能。

程序首先创建了一个 Contact 类型的变量 con,用于存储通讯录信息。然后通过调用 InitContact 函数对通讯录进行初始化。

接下来,程序进入一个 do-while 循环,不断显示菜单并等待用户输入选择。根据用户的选择,程序调用相应的函数实现添加、删除、查找、修改、显示、排序联系人信息等功能。当用户输入 0 时,程序调用 SaveContact 函数将通讯录信息保存到文件中,并调用 DestroyContact 函数销毁通讯录并释放内存。

这个通讯录管理系统可以用于管理联系人信息,提供了添加、删除、查找、修改、显示、排序联系人信息等多种功能。

4.初始化通讯录

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;
	//加载文件信息到通信录
	LoadContact(pc);
}

这段代码定义了一个名为 “InitContact” 的函数,用于初始化通讯录并为其分配内存空间。

该函数接受一个指向 Contact 类型的指针作为参数,表示要初始化的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。在函数体中,首先将通讯录的大小设置为 0,即初始时通讯录中没有联系人信息。然后使用 calloc 函数为通讯录中的联系人信息分配内存空间,分配的空间大小为 DEFAULT_SZ 个 PeoInfo 结构体,即 pc->capacity * sizeof(PeoInfo)。如果内存分配失败,则使用 perror 函数打印错误信息,并直接返回。

接着,函数调用 LoadContact 函数,将文件中保存的联系人信息加载到通讯录中。该函数的实现可以根据具体需求进行编写。

这个函数可以用于初始化通讯录并为其分配内存空间,同时将文件中保存的联系人信息加载到通讯录中。

5.创建显示通讯录菜单的函数

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

这段代码定义了一个名为 “menu” 的函数,用于显示通讯录操作的菜单,其中包括以下选项:
1.add——添加联系人
2.del——删除联系人
3.search——查找联系人
4.modify ——更改联系人
5.show——显示联系人
6.sort——排序联系人
0.exit ——保存通讯录中的信息到文件中,销毁通讯录,退出程序

6.创建通讯录扩容的函数

//检查通讯录是否需要扩容
void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增加容量
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}

这段代码定义了一个名为 “check_capacity” 的函数,用于检查通讯录是否需要扩容。

该函数接受一个指向 Contact 类型的指针作为参数,表示要检查通讯录是否需要扩容的通讯录。在函数体中,函数检查通讯录中已经存储的联系人信息个数 sz 是否等于通讯录的最大容量 capacity。如果相等,则使用动态内存分配函数 realloc 重新分配内存,将新分配的内存大小设置为 (capacity + INC_SZ) * sizeof(PeoInfo),其中 INC_SZ 表示增加的容量大小。如果内存分配失败,则打印一条错误消息并返回函数。否则,将新分配的内存的指针赋值给通讯录的 data 成员变量,将通讯录的最大容量 capacity 更新为 (capacity + INC_SZ)。

这个函数可以用于检查通讯录是否需要扩容,并在需要扩容时增加容量。

7.创建添加联系人的函数

//添加联系人(动态版本)
void AddContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	//添加一个人的信息
	printf("请输入名字:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}

这段代码定义了一个名为 “AddContact” 的函数,用于向通讯录中添加一个联系人信息。

该函数接受一个指向 Contact 类型的指针作为参数,表示要添加联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。另外,check_capacity 函数用于检查通讯录是否需要扩容。

在函数体中,首先使用 check_capacity 函数检查通讯录是否需要扩容。如果通讯录已满,则打印一条消息并返回函数。否则,提示用户输入新添加联系人的信息,包括姓名、年龄、性别、地址和电话号码,并将这些信息存储在通讯录中下一个位置的 PeoInfo 类型结构体中。最后,将通讯录中已经存储的联系人信息个数 sz 加 1。

这个函数可以用于向通讯录中添加一个联系人信息,如果通讯录已满则返回函数。

8.创建删除联系人的函数

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

这段代码定义了一个名为 “DelContact” 的函数,用于从通讯录中删除指定联系人的信息。

该函数接受一个指向 Contact 类型的指针作为参数,表示要删除联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。另外,如果通讯录中没有联系人信息则打印一条消息并返回函数。

在函数体中,首先提示用户输入要删除的联系人姓名,并使用 FindByName 函数查找该联系人在通讯录中的位置。如果该联系人不存在,则打印一条消息并返回函数。否则,从该位置开始遍历通讯录中的所有联系人,并将每个联系人的信息向前移动一个位置,以覆盖要删除的联系人信息。最后,将通讯录中已经存储的联系人信息个数 sz 减 1,并打印一条删除成功的消息。

这个函数可以用于从通讯录中删除指定联系人的信息。

9.创建查找指定联系人的函数

//查找指定联系人
void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].addr,
		pc->data[pos].tele);
}

这段代码定义了一个名为 “SearchContact” 的函数,用于在通讯录中查找指定联系人的信息。

该函数接受一个指向 const Contact 类型的指针作为参数,表示要查找联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。

在函数体中,首先提示用户输入要查找的联系人姓名,并使用 FindByName 函数查找该联系人在通讯录中的位置。如果该联系人不存在,则打印一条消息并返回函数。否则,打印联系人的姓名、年龄、性别、地址和电话信息。

这个函数可以用于在通讯录中查找指定联系人的信息。

10.创建修改指定联系人信息的函数

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

这段代码定义了一个名为 “ModifyContact” 的函数,用于修改通讯录中指定联系人的信息。

该函数接受一个指向 Contact 类型的指针作为参数,表示要修改联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。

在函数体中,首先提示用户输入要修改的联系人姓名,并使用 FindByName 函数查找该联系人在通讯录中的位置。如果该联系人不存在,则打印一条消息并返回函数。否则,提示用户输入新的联系人信息,包括姓名、年龄、性别、地址和电话号码,并将这些信息存储在通讯录中指定位置的 PeoInfo 类型结构体中。最后,打印一条修改完成的消息。

这个函数可以用于修改通讯录中指定联系人的信息。

11.创建显示通讯录信息的函数

//显示通讯录的信息
void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}

这段代码定义了一个名为 “ShowContact” 的函数,用于显示通讯录中所有联系人的信息。

该函数接受一个指向 const Contact 类型的指针作为参数,表示要显示联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。在函数体中,首先打印联系人信息的表头,包括姓名、年龄、性别、地址和电话。然后遍历通讯录中的所有联系人,逐个打印其姓名、年龄、性别、地址和电话信息。

这个函数可以用于显示通讯录中所有联系人的信息。

12.创建查找对应联系人位置的函数

int FindByName(Contact*pc,char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

这段代码定义了一个名为 “FindByName” 的函数,用于根据姓名在通讯录中查找对应联系人的位置。

该函数接受一个指向 Contact 类型的指针作为参数,表示要查找联系人信息的通讯录。同时,该函数还接受一个字符串参数 name,表示要查找的联系人姓名。函数使用循环遍历通讯录中所有的联系人信息,逐一比较姓名是否与要查找的姓名相同。如果找到对应的联系人,则返回该联系人在通讯录中的位置,否则返回 -1。

这个函数可以用于根据姓名在通讯录中查找对应联系人的位置。

13.创建按名字排序联系人信息的函数

//按名字排序联系人的信息
void SortContactName(Contact* pc)
{
	assert(pc);
	PeoInfo temp;
	for (int i = 0; i < pc->sz - 1; i++)
	{
		for (int j = 0; j < pc->sz - 1 - i; j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				temp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = temp;
			}
		}
	}
	printf("排序后为:\n");
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}

这段代码定义了一个名为 “SortContactName” 的函数,用于按照联系人姓名对通讯录中的联系人信息进行排序。

该函数接受一个指向 Contact 类型的指针作为参数,表示要排序联系人信息的通讯录。函数使用 assert 宏检查指针是否为空,以确保程序不会崩溃。在函数体中,使用冒泡排序算法对通讯录中的联系人信息进行排序,排序的关键字为联系人的姓名,使用 strcmp 函数进行比较。排序完成后,打印排序后的联系人信息表头和每个联系人的姓名、年龄、性别、地址和电话。

这个函数可以用于按照联系人姓名对通讯录中的联系人信息进行排序。

14.创建销毁通讯录的函数

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

这段代码定义了一个名为 “DestroyContact” 的函数,用于销毁通讯录并释放内存。

该函数接受一个指向 Contact 类型的指针作为参数,表示要销毁的通讯录。在函数体中,首先使用 free 函数释放通讯录中的联系人信息所占用的内存。然后将通讯录的容量和大小都设置为 0,并将通讯录指针设置为 NULL。

这个函数可以用于销毁通讯录并释放内存,避免内存泄漏。

15.保存通讯录中的信息到文件中的函数

//保存通讯录中的信息到文件中
void SaveContact(Contact* pc)
{
	//打开文件
	FILE*pf=fopen("contact.txt", "wb");
	if (NULL == pf)
	{
		perror("SaveContact");
	}
	else
	{
		//写数据
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data+i,sizeof(PeoInfo),1,pf);
		}
		fclose(pf);
		pf = NULL;
		printf("保存成功\n");
	}
}

这段代码定义了一个名为 “SaveContact” 的函数,用于将通讯录中的联系人信息保存到文件中。

该函数接受一个指向 Contact 类型的指针作为参数,表示要保存联系人信息的通讯录。在函数体中,首先使用 fopen 函数打开名为 “contact.txt” 的二进制文件,以便将联系人信息写入文件中。如果文件打开失败,则使用 perror 函数打印错误信息并直接返回。

接着,函数使用循环遍历通讯录中的联系人信息,并将每个联系人信息使用 fwrite 函数写入文件中。写入的数据包括联系人信息的地址、每个联系人信息的大小 sizeof(PeoInfo) 和写入数据量 1。这样,每次写入的数据大小就是 sizeof(PeoInfo) 字节。写入完成后,使用 fclose 函数关闭文件指针 pf,并将其设置为 NULL。

最后,函数打印保存成功的提示信息。

这个函数可以用于将通讯录中的联系人信息保存到文件中,以便下次使用时能够加载已有的联系人信息。

16.创建加载文件信息到通讯录的函数

//加载文件信息到通讯录
void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt","rb");
	if (pf == NULL)
	{
		perror("LoadContact");
	}
	else
	{
		//读数据
		PeoInfo	tmp = { 0 };
		int i = 0;
		while (fread(&tmp, sizeof(PeoInfo), 1, pf))
		{
			//增容
			check_capacity(pc);
			pc->data[i] = tmp;
			pc->sz++;
			i++;
		}
		fclose(pf);
		pf = NULL;
	}
}

17.完整源代码

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
#define DEFAULT_SZ 3
#define INC_SZ 2
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;
typedef struct Contact
{
	PeoInfo* data;//指向存放人的信息的空间
	int sz;//当前已经放的信息的个数
	int capacity;//当前通讯录的最大容量
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//显示通讯录的信息
void ShowContact(const Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人的信息
void ModifyContact(Contact* pc);
//按名字排序联系人的信息
void SortContactName(Contact* pc);
//销毁通讯录
void DestroyContact(Contact* pc);
//保存通讯录中的信息到文件中
void SaveContact(Contact* pc);
//加载文件信息到通讯录
void LoadContact(Contact* pc);
//初始化通讯录
//动态版本
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;
	//加载文件信息到通信录
	LoadContact(pc);
}

void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增加容量
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}
//添加联系人(动态版本)
void AddContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	//添加一个人的信息
	printf("请输入名字:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}
//显示通讯录的信息
void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}
int FindByName(Contact*pc,char 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)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通信录为空,无法删除\n");
		return;
	}
	//删除
	printf("请输入要删除人的名字:\n");
	scanf("%s", name);
	int ret=FindByName(pc,name);
	if (-1==ret)
	{
		printf("要删除的人不存在\n");
		return;
	}
	int i = 0;
	for (i = ret;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 (-1 == pos)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].addr,
		pc->data[pos].tele);
}
//修改指定联系人的信息
void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改的人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要修改的人不存在\n");
		return;
	}
	printf("请输入名字:");
	scanf("%s", pc->data[pos].name);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入性别:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入地址:");
	scanf("%s", pc->data[pos].addr);
	printf("请输入电话:");
	scanf("%s", pc->data[pos].tele);
	printf("修改完成\n");
}
//按名字排序联系人的信息
void SortContactName(Contact* pc)
{
	assert(pc);
	PeoInfo temp;
	for (int i = 0; i < pc->sz - 1; i++)
	{
		for (int j = 0; j < pc->sz - 1 - i; j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				temp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = temp;
			}
		}
	}
	printf("排序后为:\n");
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n",
		"姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}
//销毁通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}
//保存通讯录中的信息到文件中
void SaveContact(Contact* pc)
{
	//打开文件
	FILE*pf=fopen("contact.txt", "wb");
	if (NULL == pf)
	{
		perror("SaveContact");
	}
	else
	{
		//写数据
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data+i,sizeof(PeoInfo),1,pf);
		}
		fclose(pf);
		pf = NULL;
		printf("保存成功\n");
	}
}
//加载文件信息到通讯录
void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt","rb");
	if (pf == NULL)
	{
		perror("LoadContact");
	}
	else
	{
		//读数据
		PeoInfo	tmp = { 0 };
		int i = 0;
		while (fread(&tmp, sizeof(PeoInfo), 1, pf))
		{
			//增容
			check_capacity(pc);
			pc->data[i] = tmp;
			pc->sz++;
			i++;
		}
		fclose(pf);
		pf = NULL;
	}
}
void menu()
{
	printf("********************************************\n");
	printf("**            1.add     2.del             **\n");
	printf("**            3.search  4.modify          **\n");
	printf("**            5.show    6.sort            **\n");
	printf("**            0.exit                      **\n");
	printf("********************************************\n");
}
int main()
{

	int input;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case 1://添加联系人
			AddContact(&con);
			break;
		case 2://删除联系人
			DelContact(&con);
			break;
		case 3://查找联系人
			SearchContact(&con);
			break;
		case 4://更改联系人
			ModifyContact(&con);
			break;
		case 5://显示联系人
			ShowContact(&con);
			break;
		case 6://排序联系人
			SortContactName(&con);
			break;
		case 0:
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出通讯录");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/694458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

想知道AI智能绘画是什么?三分钟告诉你如何生成ai绘画

你是否曾经幻想过让电脑也能像大师一样创作出美丽的艺术作品&#xff1f;AI智能绘画就是这样一门神奇的技术&#xff0c;它将人工智能与绘画艺术相结合&#xff0c;为我们呈现了一场令人惊叹的创造魔术。那么到底AI智能绘画是什么呢&#xff1f;让我们一起揭开它的神秘面纱&…

低代码平台其中两大优势

低代码开发平台本质上是一种的软件开发工具&#xff0c;通过把常用功能控件进行组件化封装、将常用业务场景进行模板化&#xff0c;通过可视化模式进行进行开发。相比传统编码开发模式具有开发效率高、开发成本更低的明显优势。 低代码开发是如何提高开发效率和降低成本的呢&am…

Navicat连接oracle

1、官网下载oracle instant client客户端&#xff08;版本自选&#xff09; Oracle Instant Client Downloads 下载后解压 2、navicat配置 在工具-> 选项 -> OCI 或环境中&#xff0c;选择在步骤 1 解压目录的 oci.dll 3、重新启动 Navicat 4、配置oracle连接即可 参考…

Excel 经常复制粘贴失效,复制表格粘贴不了无反应,怎么解决?

环境&#xff1a; Win10 专业版 Excel2021 L盾加密客户端 wps2021 问题描述&#xff1a; 之前正常的&#xff0c;excel2016和2021 经常复制表格粘贴不了无反应每隔10几分钟随机出现&#xff0c;在表格外面复制粘贴没有问题&#xff0c;把外面东西&#xff0c;粘贴进表格里…

阿里一年香~

一年香照片&纪念品 一年香感悟 身份转变 从学生身份变为社会打工人&#xff0c;深知父母挣钱的不易与艰辛&#xff0c;也懂得了朝十晚九的生活。不要焦虑&#xff0c;开心过好每一天。 沉稳与笨拙 从原来的120斤到现在的140斤&#xff0c;真是又沉又稳。现在周六上午打…

Android JNI 学习实践

目录介绍 01.学习JNI开发流程 1.1 JNI开发概念1.2 JNI和NDK的关系1.3 JNI实践步骤1.4 NDK使用场景1.5 学习路线说明 02.NDK架构分层 2.1 NDK分层构建层2.2 NDK分层Java层2.3 Native层 03.JNI基础语法 3.1 JNI三种引用3.2 JNI异常处理3.3 C和C互相调用3.4 JNI核心原理3.5 注册N…

应用自动开启辅助(无障碍)功能并使用辅助(无障碍)功能

一.背景 由于最近的项目需要开启无障碍功能然后实现对应的功能需求,但是由于需求是需要安装后就开启辅助功能,不要在繁琐的在设置中开启辅助功能,所以需要如何在应用中开启辅助功能。 二.前提条件 将普通应用转换成系统应用,然后将系统的framework.jar包放到应用中并且可以…

【知识总结】邀请功能的实现分析

邀请功能 功能分析 场景&#xff1a;项目中出现用户邀请其他用户加入群组的功能 需求&#xff1a;用户点击生成邀请链接可以生成一个url&#xff0c;将这个url分享给其他用户&#xff0c;其他用户点击后对用户登录状态进行校验&#xff0c;校验通过即可加入群组&#xff0c;…

QLORA:量化LLMA的有效微调

文章目录 摘要1、简介2、背景3、QLORA微调4、QLoRA vs.标准微调5、用QLoRA推动聊天机器人达到最高水平5.1、实验设置5.2、评价5.3、Guanaco:在OASST1上使用QLORA训练的最先进的聊天机器人 6、定性分析6.2、注意事项 7、相关工作8、限制与讨论9、更广泛的影响致谢QLoRA与标准微调…

css实现毛玻璃磨砂效果

预览效果 实现原理&#xff1a; backdrop-filter CSS 属性可以让你为一个元素后面区域添加图形效果&#xff08;如模糊或颜色偏移&#xff09;。 因为它适用于元素背后的所有元素&#xff0c;为了看到效果&#xff0c;必须使元素或其背景至少部分透明。 完整代码&#xff1a; …

3D创作应用《Masterpiece X》上线Quest平台

6月25日青亭网报道&#xff0c;《Masterpiece X》是一款3D创作类应用&#xff0c;主要特点是通过面向普通用户&#xff0c;提供更简单易用的创作工具。目前已经上线Quest 2和Quest Pro&#xff0c;重要的是这是一款免费工具。 该作来自于Masterpiece Studio&#xff0c;开发历经…

百度脑图切换账号

当然是清除cookie了&#xff01; 方法 在百度脑图页面右键&#xff0c;点检查 点小箭头&#xff0c;找到应用 找到cookie下的naotu.baidu.com&#xff0c;右键清除&#xff0c;然后刷新页面 重新登录&#xff0c;就有了

HTML系列

快捷键 表格快捷键&#xff1a;table>trn>tdn{a}&#xff08;n行n列&#xff0c;内容均为a&#xff09;无序列表快捷键&#xff1a;ul>li*n&#xff08;n代表无序列表的数量&#xff09; 对应表格快捷产出的样式&#xff08;不用管table内的参数设置&#xff0c;这里…

在windows上可视化redis中间件

首先需要下载一下RedisDesktopManager这个可视化工具&#xff0c;在很多CSDN博客上都有博主进行介绍&#xff0c;其实就是一个傻瓜式安装。 windows下安装redis的话可以去B站上查看一下怎么安装&#xff0c;主要是在github上去下载&#xff0c;目前更新的比较快&#xff0c;不…

winform项目-C#面向对象程序设计,深入浅出入门和进阶实战开发解决方案必知点 3 数组,循环,判断的综合案例,业务场景的初步应用尝试和快速实现

只能说白天真的很多的事情&#xff0c;但是具体什么事情呢&#xff0c;哦&#xff0c;好像去了一趟码家&#xff0c;然后上午的时间就一直在那边了&#xff0c;哄孩子&#xff0c;sister and boy。别人看起来&#xff0c;好像要说儿女双全了呢&#xff0c;不是非常令人羡慕的事…

Jetson 开机报错:no module named jtop.core.jetson_variables

环境说明&#xff1a; ubuntu18.04&#xff0c;python3.6. jetpack4.6.4&#xff0c;jetson-stats4.0.0rc3 开机报错如下 报错分析 Error found when loading /etc/profile, 因此打开该文件查看&#xff0c;文件内容指向 /etc/profile.d 文件夹&#xff0c;打开该文件夹 发现存…

uni-app uni.switchTab和uni.reLaunch跳转tabbar页面

uni.switchTab&#xff1a; 跳转列表不会刷新 跳转到 tabBar 页面&#xff0c;并关闭其他所有非 tabBar 页面。 uni.reLaunch&#xff1a; 跳转列表会刷新 关闭所有页面&#xff0c;打开到应用内的某个页面。&#xff08;可以跳转到tabBar 页面&#xff09; 但如果是列表的自定…

软考高级系统架构设计师(六) 企业信息化战略与实施

目录 概要 信息 信息系统战略规划 信息系统生命周期 政府信息与电子政务 ERP企业资源计划 CRM 客户关系管理 SCM 供应链管理 BI 商业智能 数据湖 ​BPR和BPM 概要 信息 信息系统战略规划 第一阶段&#xff1a; 练习题&#xff1a; 信息系统生命周期 政府信息与电子政…

leecode-二分查找

题目 题目链接 分析 大家都知道二分查找其实有很多种写法&#xff0c;这里一个比较巧妙地点就是&#xff0c;这个写法可以在返回插入位置的时候直接返回i&#xff0c;不用进行处理。 那么为什么这种写法可以呢&#xff1f; 我们来分析一下&#xff0c;首先我们的写法是&…

区块链技术-溯源管理系统源码

技术架构&#xff1a;spring bootmybatiseasyuimysql 粮油生产质量追溯系统 粮油生产质量追溯系统可广泛用于粮油生产加工领域。实现种植主体、种植基地、生产计划、压榨、精炼、包装、销售、物料管理、检验检测等各个环节的数据采集&#xff0c;达到正向可追踪&#xff0c;反…