C 언어 프로젝트 연습 주소록 (3 가지 버전의 공동 분해)

프로젝트 설명

전화 번호는 현대의 커뮤니케이션에 없어서는 안될 필수 요소이지만, 연락 할 친구 나 사람이 너무 많아서 전화 번호를 적어 두어야합니다.하지만 장부 기록과 질의가 너무 번거롭기 때문에 컴퓨터 프로그래밍을 사용하여 다기능적이고 포괄적 인 주소록은 이러한 전화 번호를보다 편리하게 처리하는 데 도움이됩니다.

대상 기능은 다음을 포함합니다.

  1. 연락처 정보 추가
  2. 지정된 연락처 정보 삭제
  3. 특정 연락처 정보 찾기
  4. 모든 연락처 정보 표시
  5. 모든 연락처 지우기
  6. 모든 연락처를 이름으로 정렬
  7. 파일에 연락처 저장 (파일 버전)
  8. 파일에서 연락처로드 (파일 버전)

완료 할 세 가지 버전이 있습니다.

  1. 구조 버전 (기본 버전)
  2. 동적 메모리 버전
  3. 파일 작업 버전

프로젝트 아이디어

플로우 차트

주요 기능은 해당 기능으로 캡슐화됩니다.
여기에 사진 설명 삽입
여기에 사진 설명 삽입

프로젝트에 사용 된 지식 포인트

  1. 구조 사용
  2. 동적 메모리 사용 malloc realloc calloc free
  3. 파일 작업

프로젝트 기능 실현

함수 선언 및 추상 대상

1. 초록 개인 정보

typedef struct PersonInfo 
{
    
     
char name[MAX_NAME]; 
char sex[SEX_NAME]; 
short age; 
char tele[TEL_NAME]; 
char addr[TEL_NAME]; 
}PersonInfo;

2. 초록 주소록

typedef struct Contact {
    
     
//PersonInfo per[MAX_PER_NUM] ;静态版本 
int usedsize;//有效数据个数 动态版本 
PersonInfo* per; //动态版本
int capacity;//初始容量 
}Contact;//通讯录

기능 구현 필요 :

#ifndef __CONTACT_H__ 
#define __CONTACT_H__ 
#include<string.h> 
#include<stdio.h> 
#include<assert.h> 
#include<stdlib.h> 
enum Option 
{
    
     
EXIT, 
ADD, 
DEL, 
SEARCH, 
MONDIFY, 
SHOW, 
EMPTY, 
SORT 
};
#define MAX_NAME 20 
#define SEX_NAME 5 
#define TEL_NAME 12 
#define ADDR_NAME 20 //通讯录最多为1000人 
#define MAX_PER_NUM 1000 //动态扩容版本 
#define DEFAULT_SIZE 2; 
typedef struct PersonInfo 
{
    
     
char name[MAX_NAME]; 
char sex[SEX_NAME]; 
short age;
char tele[TEL_NAME]; 
char addr[TEL_NAME]; 
}PersonInfo; 
typedef struct Contact 
{
    
     
//PersonInfo per[MAX_PER_NUM] ;普通版本 
PersonInfo* per; 
int usedsize;//有效数据个数 
int capacity;//初始容量 
}Contact;//通讯录 
//初始化通讯录 
void InitContact(Contact *con); 
//添加成员 
void AddContact(Contact *con); 
//打印通讯录 
void ShowContact(Contact *con); 
//删除成员 
void DelContact(Contact *con); 
//查找成员 
int SearchContact(Contact *con); 
//清空通讯录 
void EmptyContact(Contact *con); 
//摧毁通讯录(动态版本) 
void DestoryContact(Contact *con); 
//文件版本 //保存联系人到文件 
void SaveContact(Contact *con); 
//加载联系人 
void LoadContact(Contact *con); 
#endif //__CONTACT_H__

주요 기능의 아키텍처 및 구성

#include"contact.h"


void menu() {
    
    
	printf("******************通讯录********************\n");
	printf("*** 1.add   2.show    3.delete 4.search ****\n");
	printf("*** 5.empty 6.distory 7.save   8.load   ****\n");
	printf("***************** 0.quit *******************\n");
	printf("********************************************\n");
}

int main()
{
    
    
	int select = 0;
	Contact contact;
	InitContact(&contact);
	do{
    
    
		menu();
		printf("Pleas intput you changce:");
		scanf("%d", &select);

		switch (select)
		{
    
    
		case QUIT: 
			printf("Good bye!\n");
			break;
		case ADD:
			AddContact(&contact);
			break;
		case SHOW:
			ShowContact(&contact);
			break;
		case DEL:
			DelContact(&contact);
			break;
		case SEARCH:
			SearchContact(&contact);
			break;
		case EMPTY:
			EmptyContact(&contact);
			break;
		case DESTORY:
			DestoryContact(&contact);
			break;
		case SAVE:
			SaveContact(&contact);
			break;
		case LOAD:
			LoadContact(&contact);
			break;
		default:
			break;
		}
	} while (select);
	system("pause");
	return 0;
}

주소록 초기화

void InitContact(Contact *pcon) {
    
    
	//普通版本
	//pcon->usedSize = 0; 
	//memset(pcon->per,0,sizeof(pcon->per));

	pcon->usedsize = 0;
	pcon->capacity = DEFAULT_SIZE;
	pcon->per = (PersonInfo *)malloc(
		sizeof(PersonInfo) * pcon->capacity);
	assert(pcon->per != NULL);

	LoadContact(pcon);//有可能文件中也有存储的联系人
}

연락처로드

void LoadContact(Contact *pcon) {
    
    
	FILE *pf = fopen("Contact.bat", "rb");
	PersonInfo tmp = {
    
     0 };
	if (pf == NULL)
	{
    
    
		return;
	}
	//fread函数的返回值是:读取成功的字节数
	while (fread(&tmp, sizeof(PersonInfo), 1, pf) > 0)
	{
    
    
		//必须判断是否为满,如果满了扩容
		CheckFullAndRe(pcon);
		pcon->per[pcon->usedsize++] = tmp;
	}
	fclose(pf);
	pf = NULL;
}

회원 추가

void AddContact(Contact *pcon) {
    
    
	//普通版本,无扩容解决办法
	//if(pcon->usedSize == MAX_NUMBER)
	//{
    
    
	//	printf("this contact is full\n");
	//	return;
	//}

	if (CheckFullAndRe(pcon) != 1)
	{
    
    
		printf("扩容失败\n");
		return;
	}

	printf("请输入姓名:");
	scanf("%s", pcon->per[pcon->usedsize].name);
	printf("请输入年龄:");
	scanf("%d", &(pcon->per[pcon->usedsize].age));
	printf("请输入性别:");
	scanf("%s", pcon->per[pcon->usedsize].sex);
	printf("请输入电话:");
	scanf("%s", pcon->per[pcon->usedsize].tele);
	printf("请输入住址:");
	scanf("%s", pcon->per[pcon->usedsize].addr);
	pcon->usedsize++;
	printf("添加成功\n");
}

주소록 인쇄

void ShowContact(Contact *pcon) {
    
    
	int i = 0;
	printf("%-10s %-5s %-5s %-11s %-20s\n", "姓名", "年龄",
		"性别", "电话", "住址");
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		printf("%-10s %-5d %-5s %-11s %-20s\n",
			pcon->per[i].name, pcon->per[i].age,
			pcon->per[i].sex, pcon->per[i].tele,
			pcon->per[i].addr);
	}
}

회원 삭제

void DelContact(Contact *pcon) {
    
    
	int index = SearchContact(pcon);
	int i = 0;
	if (index == -1)
	{
    
    
		printf("删除失败,查无此人\n");
		return;
	}
	for (i = index; i < pcon->usedsize - 1; i++)
	{
    
    
		pcon->per[i] = pcon->per[i + 1];
	}
	pcon->usedsize--;
	printf("删除成功\n");
}

회원 찾기

int SearchContact(Contact *pcon) {
    
    
	int i = 0;
	char name[MAX_NAME] = {
    
     0 };
	if (pcon->usedsize == 0)
	{
    
    
		printf("通讯录为空\n");
		return -1;
	}
	printf("请输入你要删除的姓名:");
	scanf("%s", name);
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		if (strcmp(pcon->per[i].name, name) == 0)
		{
    
    
			return i;
		}
	}
	return -1;
}

빈 주소록

void EmptyContact(Contact *pcon) {
    
    
	pcon->usedsize = 0;
}

주소록 삭제 (동적 버전)

void DestoryContact(Contact *pcon) {
    
    
	SaveContact(pcon);
	free(pcon->per);
	pcon->per = NULL;//预防野指针  
	pcon->capacity = 0;
	pcon->usedsize = 0;
}

파일에 연락처 저장 (파일 버전)

void SaveContact(Contact *pcon) {
    
    
	int i = 0;
	FILE *pf = fopen("Contact.bat", "wb");
	assert(pf != NULL);
	for (i = 0; i < pcon->usedsize; i++)
	{
    
    
		fwrite(pcon->per + i, sizeof(PersonInfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

발생한 문제

주소록이 정적 버전이든 동적 버전이든 관계없이 저장되는 사용자 수에는 제한이 있습니다.

동적 메모리는 필요한만큼 열 수 있지만 프로그래밍에서 정의해야합니다.

해결책

확장 기능을 설계하고 저장 공간이 부족하면 더 많은 메모리를 엽니 다.

주소록 확장

static int CheckFullAndRe(Contact *pcon) {
    
    
	if (pcon->usedsize == pcon->capacity)
	{
    
    
		PersonInfo * ptr = NULL;
		ptr = (PersonInfo *)realloc(pcon->per,
			sizeof(PersonInfo) * pcon->capacity * 2);
		if (ptr != NULL)
		{
    
    
			pcon->per = ptr;
			pcon->capacity *= 2;
			printf("扩容成功\n");
			return 1;
		}
		else
		{
    
    
			return 0;//扩容失败
		}
	}

	return 1;
}

프로젝트 소스 코드

내 주소록 프로젝트의 소스 코드 : https://github.com/GagaAutom/C-programming-language/blob/master/my_contact/contact

추천

출처blog.csdn.net/qq_40893595/article/details/105547369