9 월 8 일 가을이 오면 꽃이 피고 꽃 100 송이를 죽 이겠습니다
프로젝트 설명
전화 번호는 현대의 커뮤니케이션에 없어서는 안될 필수 요소이지만, 연락 할 친구 나 사람이 너무 많아서 전화 번호를 적어 두어야합니다.하지만 장부 기록과 질의가 너무 번거롭기 때문에 컴퓨터 프로그래밍을 사용하여 다기능적이고 포괄적 인 주소록은 이러한 전화 번호를보다 편리하게 처리하는 데 도움이됩니다.
대상 기능은 다음을 포함합니다.
- 연락처 정보 추가
- 지정된 연락처 정보 삭제
- 특정 연락처 정보 찾기
- 모든 연락처 정보 표시
- 모든 연락처 지우기
- 모든 연락처를 이름으로 정렬
- 파일에 연락처 저장 (파일 버전)
- 파일에서 연락처로드 (파일 버전)
완료 할 세 가지 버전이 있습니다.
- 구조 버전 (기본 버전)
- 동적 메모리 버전
- 파일 작업 버전
프로젝트 아이디어
플로우 차트
주요 기능은 해당 기능으로 캡슐화됩니다.
프로젝트에 사용 된 지식 포인트
- 구조 사용
- 동적 메모리 사용 malloc realloc calloc free
- 파일 작업
프로젝트 기능 실현
함수 선언 및 추상 대상
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