9月8日に秋になると花が咲いたら百花を殺す
プロジェクトの説明
現代のコミュニケーションには電話番号が不可欠ですが、友達や人が多すぎて連絡できないため、電話番号を書き留める必要があります。しかし、本の記録やクエリは面倒なので、コンピュータプログラミングを使用して多機能で包括的なものにすることができますアドレス帳は、これらの電話番号をより便利に処理するのに役立ちます。
ターゲット関数は以下をカバーします:
- 連絡先情報を追加
- 指定した連絡先情報を削除します
- 特定の連絡先情報を見つける
- すべての連絡先情報を表示
- すべての連絡先をクリア
- すべての連絡先を名前で並べ替え
- 連絡先をファイルに保存(ファイルバージョン)
- ファイルから連絡先を読み込む(ファイルバージョン)
完了するには3つのバージョンがあります。
- 構造バージョン(基本バージョン)
- 動的メモリバージョン
- ファイル操作バージョン
プロジェクトのアイデア
フローチャート
メイン関数は対応する関数にカプセル化されています
プロジェクトで使用される知識ポイント
- 構造の使用
- 動的メモリの使用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