C语言练习 -- 通讯录

 练习使用了结构体,动态内存管理malloc函数,文件读写函数

//main.c
#include "contacts.h"

enum choose
{
	EXIT,
	ADD,
	DEL,
	MODIFY,
	FIND,
	SORT
};

int main()
{
	int input = 0;
	//通讯录当前联系人个数
	int size = 0;
	Contacts contacts;//创建通讯录
	InitContacts(&contacts);

	do
	{
		menu();
		printf("Pleae choose:> ");
		scanf_s("%d", &input);

		switch (input)
		{
		case 0:
			Write_to_File(&contacts);
			FreeContacts(&contacts);
			break;
		case 1:
			Add(&contacts);
			break;
		case 2:
			Del(&contacts);
			break;
		case 3:
			Modify(&contacts);
			break;
		case 4:
			Find(&contacts);
			break;
		case 5:
			Sort(&contacts);
			break;
		case 6:
			Print(&contacts);
			break;
		default:
			printf("Wrong! Please input again.\n");
			break;
		}
	} while (input);
	

	return 0;
}

main.c用于实现基本框架,选择进入相应功能 

//contacts.c
#include "contacts.h"

void menu()
{
	printf("############################\n");
	printf("### 1.ADD ####### 2. DEL ###\n");
	printf("### 3.MODIFY #### 4.FIND ###\n");
	printf("### 5.SORT #### 6. PRINT ###\n");
	printf("### 0.EXIT #################\n");
	printf("############################\n");
}

void InitContacts(Contacts* pf)
{
	pf->data = (Info*)malloc(DEFAULT_SZ*sizeof(Info));
	if (pf->data == NULL)
	{
		perror("InitContacts");
		return;
	}
	pf->num = 0;
	pf->size = DEFAULT_SZ;
	memset(pf->data, 0, DEFAULT_SZ * sizeof(Info));
	Read_from_File(pf);
}

void Add(Contacts* pf)
{
	Enlarge(pf);
	printf("Please Input Name:> ");
	scanf_s("%s", pf->data[pf->num].name, 20);
	printf("Please Input Sex:> ");
	scanf_s("%s", pf->data[pf->num].sex, 10);
	printf("Please Input Age:> ");
	scanf_s("%d", &(pf->data[pf->num].age));
	printf("Please Input Phone Number:> ");
	scanf_s("%s", pf->data[pf->num].phone, 12);
	(pf->num)++;
}

void Del(Contacts* pf)
{
	char temp[20] = { 0 };
	printf("Please input the Name you want to delete:> ");
	scanf_s("%s", temp, 20);
	for (size_t i = 0; i < pf->num; i++)
	{
		if (strcmp(temp, pf->data[i].name) == 0)
		{
			printf("Delete succeeded.\n");
			//将data[i+1]和之后的所有数据前移,覆盖要删除的数据
			memmove((pf->data)+i, (pf->data)+i+1, (pf->size-i)*sizeof(pf->data[0]));
			(pf->num)--;
			return;
		}
	}
	printf("Can't delete.No such a person.\n");
}

void Modify(Contacts* pf)
{
	char temp[20] = { 0 };
	printf("Please input the Name you want to modify:> ");
	scanf_s("%s", temp, 20);
	for (size_t i = 0; i < pf->num; i++)
	{
		if (strcmp(temp, pf->data[i].name) == 0)
		{
			printf("Please Input new Name:> ");
			scanf_s("%s", pf->data[i].name, 20);
			printf("Please Input new Sex:> ");
			scanf_s("%s", pf->data[i].sex, 10);
			printf("Please Input new Age:> ");
			scanf_s("%d", &pf->data[i].age);
			printf("Please Input new Phone Number:> ");
			scanf_s("%s", pf->data[i].phone, 12);
			printf("Modify succeeded:> \n");
			printf("%-20s\t%-10s\t%-3s\t%-12s\n", "Name", "Sex", "Age", "Phone Number");
			printf("%-20s\t%-10s\t%-3d\t%-12s\n", pf->data[i].name,
				pf->data[i].sex,
				pf->data[i].age,
				pf->data[i].phone);
			return;
		}
	}
	printf("Can't modify.No such a person.\n");
}

void Find(const Contacts* pf)
{
	char temp[20] = { 0 };
	printf("Please input the Name you want to find:> ");
	scanf_s("%s", temp, 20);
	for (size_t i = 0; i < pf->num; i++)
	{
		if (strcmp(temp, pf->data[i].name) == 0)
		{
			printf("Search succeeded.\n");
			printf("%-20s\t%-10s\t%-3s\t%-12s\n", "Name", "Sex", "Age", "Phone Number");
			printf("%-20s\t%-10s\t%-3d\t%-12s\n", pf->data[i].name,
				pf->data[i].sex,
				pf->data[i].age,
				pf->data[i].phone);
			return;
		}
	}
	printf("Can't find.\n");
}

void Sort(Contacts* pf)
{
	Info temp = pf->data[0];
	Info* pc = &temp;
	int flag = pf->num;
	int is_ordered = 0;//置1时代表已经按序排列
	while (flag && !is_ordered)
	{
		for (size_t i = 0; i < (pf->num) - 1; i++)
		{
			if (strcmp(pf->data[i].name, pf->data[i + 1].name) <= 0)
				is_ordered = 1;
			else if (strcmp(pf->data[i].name, pf->data[i + 1].name) > 0)
			{
				memcpy(pc, &(pf->data[i + 1]), sizeof(pf->data[0]));
				memcpy(&(pf->data[i + 1]), &(pf->data[i]), sizeof(pf->data[0]));
				memcpy(&(pf->data[i]), pc, sizeof(pf->data[0]));
				is_ordered = 0;
			}
		}
		flag--;
	}
}

void Print(const Contacts* pf)
{
	printf("%-20s\t%-10s\t%-3s\t%-12s\n", "Name", "Sex", "Age", "Phone Number");
	if (pf->num == 0)
	{
		printf("Contacts is Null.\n");
		return;
	}
	for (size_t i = 0; i < pf->num; i++)
	{
		printf("%-20s\t%-10s\t%-3d\t%-12s\n",
			pf->data[i].name,
			pf->data[i].sex,
			pf->data[i].age,
			pf->data[i].phone);
	}
}

//使用文件data.txt初始化
void Read_from_File(Contacts* pf)
{
	int i = 0;
	FILE* pfile = fopen("data.txt", "r");
	if (pfile == NULL)
	{
		perror("fopen");
		return;
	}
	while (1)
	{
		Enlarge(pf);
		if (fscanf(pfile, "%s %s %d %s\n",
			pf->data[i].name,
			pf->data[i].sex,
			&(pf->data[i].age),
			pf->data[i].phone) == EOF)
			break;
		i++;
		(pf->num)++;
	}
	printf("Contacts Init successed.\n");
	fclose(pfile);
	pfile = NULL;
}

void Write_to_File(Contacts* pf)
{
	FILE* pfile = fopen("data.txt", "w");
	if (pfile == NULL)
	{
		perror("fopen");
		return;
	}
	for (size_t i = 0; i < pf->num; i++)
	{
		fprintf(pfile, "%s %s %d %s\n",
			pf->data[i].name,
			pf->data[i].sex,
			pf->data[i].age,
			pf->data[i].phone);
	}
	fclose(pfile);
	pfile = NULL;
}

void Enlarge(Contacts* pf)
{
	if (pf->num == pf->size)
	{
		Info* ptr = (Info*)realloc(pf->data, (INC_SZ + pf->size)*sizeof(Info));
		if (ptr != NULL)
		{
			printf("Enlarge Contacts.\n");
			pf->data = ptr;
			pf->size += INC_SZ;
		}
		else
		{
			perror("realloc");
			return;
		}
	}
}

void FreeContacts(Contacts* pf)
{
	free(pf->data);
	pf->data = NULL;
}

 contacts.c用于实现各种功能

//contacts.h
#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 1000
//默认初始通讯录大小
#define DEFAULT_SZ 5
//扩大通讯录容量时每次增加的大小
#define INC_SZ 2

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>

typedef struct information
{
	int age;
	char sex[10];
	char name[20];
	char phone[12];

}Info;

//动态大小通讯录
typedef struct contacts
{
	Info* data;
	int num;//通讯录当前有效信息
	int size;//通讯录最大容量
}Contacts;

//初始菜单
void menu();

//初始化通讯录
void InitContacts(Contacts* pf);

//添加联系人
void Add(Contacts* pf);

//删除联系人
void Del(Contacts* pf);

//修改联系人
void Modify(Contacts* pf);

//查找联系人
void Find(const Contacts* pf);

//对联系人按姓名首字母由a-z排序
void Sort(Contacts* pf);

//打印联系人
void Print(const Contacts* pf);

//从文件中读取数据
void Read_from_File(Contacts* pf);

//写入修改到文件
void Write_to_File(Contacts* pf);

//释放为通讯录开辟的动态空间
void FreeContacts(Contacts* pf);

//增大通讯录的空间
void Enlarge(Contacts* pf);

 contacts.h函数声明,结构体定义和头文件包含。

使用时在项目文件夹下创建一个data.txt用于存放数据。

 

        写完这段代码后看了一本关于代码风格的书,发现有很多不足点。例如Read_from_File,Write_to_File函数命名,大小写字母命名和下划线不应该混合使用。在结构体定义时用typedef将通讯录结构体命名为了Contacts,而在创建结构体时创建名为contacts,当时没有意识到,后续使用时很容易混淆。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值