序文
書き方を知っている人は、実際には理解できないかもしれません. この記事は、ステーション B の Brother Peng の書き方のテクニックを組み合わせており、知識ポイントを段階的に進め、コードの書き方を段階的に教えています. 初心者が学ぶのに非常に適しています. 、繰り返し見ることをお勧めします。
同時に、著者、私は C 言語ステーション B の初心者でもあり、一緒に学び、コミュニケーションし、批判し、修正することを歓迎します。
家族の皆さん、ここに来て、あなたの小さな手を使って金持ちになり、私のように少し注目してください。あなたのサポートが私の創造の原動力です。誰もが一緒に学べる高品質の記事を引き続き公開します。
授業前に話す
まず、書くときは、アドレス帳の機能を理解する必要があります. 実は、アドレス帳は私たちのノートであり、連絡先情報を記録するためだけに使用されます. 重要なことは、アドレス帳を変更することです. アドレス帳の原理の実現は実際には非常に簡単です。配列を作成し、この配列を追加、削除、チェック、および変更するだけです。アドレス帳を作成するための基本的な手順のほとんどは、この領域から始まります。次のアドレス帳の編集では、いくつかの基本的な知識ポイントと組み合わせて、段階的に説明します。
メニューの実装
メニューとメニューキーを印刷する
印刷メニューとメニュー キー全体の実装ロジックを見る前に、定義したヘッダー ファイルで行ったことを見てみましょう。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
enum Option
{
EXIT,
ADD,
DEL,
SAERCH,
MOD,
SHOW,
SAVE
};
それは正しい!列挙型を作成しました。その機能は、列挙型定数を使用して 0 ~ 6 の数字を置き換えることです。もちろん、このヘッダー ファイルはソース ファイルで参照する必要があります。
#define _CRT_SECURE_NO_WARNINGS 1
#include"teat2.h"
void menu()
{
printf("*********************************************************\n");
printf("****************** 1.add 2.del ********************\n");
printf("****************** 3.saerch 4.modify ********************\n");
printf("****************** 5.show 6.save ********************\n");
printf("****************** 0.exit ********************\n");
printf("*********************************************************\n");
}
int main()
{
int arr = 0;
//创建通讯录
struct Contact con;
//通讯录初始化
InitContact(&con);
do {
menu();
printf("请输入->\n");
scanf("%d", &arr);
switch (arr)
{
//添加联系人
case ADD:
AddContact(&con);
break;
//删除联系人
case DEL:
DelContact(&con);
break;
//查找联系人
case SAERCH:
SaerchContact(&con);
break;
//修改联系人
case MODify:
SavveContact(&con);
ModContact(&con);
break;
//显示通讯录名单
case SHOW:
Contactcpy(&con);
break;
//保存联系人
case SAVE:
SavveContact(&con);
printf("保存成功!\n");
break;
case EXIT:
//指针指空
DestroyContact(&con);
printf("你已经退出。\n");
break;
default:
printf("你的输入有错,请重新输入!\n");
break;
}
} while (arr);
return 0;
}
大文字と小文字の同じ効果、および大文字小文字の後の値は、数字ではなく文字になります.これは非常に高度ですか? ユーザーは使用時に番号も入力します。
列挙の役割は何ですか?
通常、列挙定数のデフォルトの割り当てを変更せずに前から後ろに、各列挙の定数は 0、1、2、3、4... であるため、最後の列挙定数まで +1 です。メニュー キーと同じように、EXIT = 0、ADD = 1、DEL = 2、SAERCH = 3、MODIFY = 4、SHOW = 5、SAVE = 6 です。
その他の switch 分岐、while ループ、ライブラリ関数のヘッダー ファイルの参照については、ここでは説明していません。わからない場合は、私の他の記事を読むか、Q me を参照してください。
効果を見てみましょう:
アドレス帳の作成とアドレス帳の初期化
main() でアドレス帳の作成とアドレス帳の初期化
構造体とカスタム関数を作成します
//创建通讯录
struct Contact con;
//通讯录初始化
InitContact(&con);
定義したヘッダー ファイルで行ったことを見てみましょう。
#define DEFAULT_SZ 3
#define MAX_NAME 20
#define MAX_SEC 5
#define MAX_TELE 12
#define MAX_ADDR 20
//存放我们联系人的基本信息
struct Peotnfo
{
char name[MAX_NAME];
int age;
char sec[MAX_SEC];
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
//通讯录
struct Contact
{
struct Peotnfo* data;
int size;
int capacity;
};
ヘッダー ファイルに Contact 構造体を完全に記述しました. この構造体は、連絡先、連絡先の数を記録する int 変数サイズ、および連絡先数用のスペースを開く int 変数容量を格納するために使用されます.連絡先の基本情報を格納するために使用される構造体でもあることに注意してください. この構造体では、name (名前)、age (年齢)、sec (性別)、Tale (電話)、 addr (アドレス) とそれらのためのスペースを開きました。
ここで #define は数字の代わりに大文字を使用し、数字は配列がメモリ内で適用したスペースの量を示します。
超重要!! ! ! 最初に、#define 設定によって開かれるスペースは、基本的なストレージ要件を満たす必要があります. たとえば、ここで電話番号によって開かれるスペースは 12 より大きくなければなりません. そうしないと、問題が確実に発生します.
アドレス帳の初期化の具体的な実装 (動的配列を開く)
void InitContact(struct Contact* pc)
{
pc->data = (struct Peotnfo*)malloc( DEFAULT_SZ * sizeof(struct Peotnfo));
if (pc->data == NULL)
{
return;
}
//空间初始化为3,DEFAULT_SZ在头文件中指定为3
pc->capacity = DEFAULT_SZ;
pc->size = 0;
}
関数に構造体ポインターを渡し、ポインター pc と名付け、malloc ライブラリー関数を使用して動的にスペースを開きます. data はポインターであり、連絡先の基本情報を格納する構造体を指します. 厳密にするために、ifpc->data == NULL という文を追加して、有効かどうかを判断しました。
動的バージョン展開の具体的な実装形態
void CheckCapacity(struct Contact* pc)
{
if (pc->size == pc->capacity)
{
struct Peotnfo* p = (struct Peotnfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(struct Peotnfo));
if (p != NULL)
{
pc->capacity += 2;
pc->data = p;
printf("增容成功!\n");
}
else {
printf("增容失败!\n");
}
}
}
ファイルへの格納の具体的な実装
//写入文件
void SavveContact(struct Contact* pc)
{
//二进制wb写入,增加保密性
FILE* pfwrite = fopen("contat.txt", "wb");
if (pfwrite == NULL)
{
printf("%d\n", strerror(errno));
return;
}
int i = 0;
for (i = 0; i < pc->size; i++)
{
fwrite(&(pc->data[i]), sizeof(Peotnfo), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
//从文件里读
void LoadContat(struct Contact* pc)
{
Peotnfo tmp = { 0 };
FILE* pfwrites = fopen("contat.txt", "rb");
if (pfwrites == NULL)
{
printf("%d\n", strerror(errno));
return;
}
while (fread(&tmp, sizeof(Peotnfo), 1, pfwrites))
{
CheckCapacity(pc);
pc->data[pc->size] = tmp;
pc->size++;
}
fclose(pfwrites);
pfwrites = NULL;
}
これで「contat.txt」(自動作成)ファイルに連絡先情報を保存することができ、開くたびに前回の記録が残りますが、忘れずに保存しておく必要があります。fopen と fread の詳細な構文については、近日中に追いつきますので、ホームページに注目してください。
効果を見てみましょう:
最初の項目を完了し、連絡先を追加します
void AddContact(struct Contact* pc)
{
char arr1;
CheckCapacity(pc);
do {
printf("请输入名字->");
scanf("%s", pc->data[pc->size].name);
printf("请输入年龄->");
scanf("%d", &(pc->data[pc->size].age));
printf("请输入性别->");
scanf("%s", pc->data[pc->size].sec);
printf("请输入电话->");
scanf("%s", pc->data[pc->size].tele);
printf("请输入地址->");
scanf("%s", pc->data[pc->size].addr);
getchar();
pc->size++;
printf("添加完成!是否继续添加->y/n");
scanf("%c", &arr1);
getchar();
if (arr1 == 'n')
{
break;
}
} while (1);
}
ここで話すことは何もありません。scanf 関数を使用して値を pc に対応するポインターに入力し、while ループを使用して連続性を維持するだけです。
効果を見てみましょう:
5 番目の項目を完了する: アドレス帳リストを表示する
void Contactcpy(struct Contact* pc)
{
int arr2;
if (pc->size == 0)
{
printf("通讯录为空\n");
}
else {
for (arr2 = 0; arr2 < pc->size; arr2++) {
printf("名字: ");
printf("%-20s\n", pc->data[arr2].name);
printf("年龄: ");
printf("%-4d\n", (pc->data[arr2].age));
printf("性别: ");
printf("%-5s\n", pc->data[arr2].sec);
printf("电话: ");
printf("%-12s\n", pc->data[arr2].tele);
printf("地址: ");
printf("%-30s\n", pc->data[arr2].addr);
printf("---------------------------\n");
}
}
}
ここで話すことは何もありません。printf 関数を使用して連絡先情報を出力するだけです。ここにあらかじめ書き込んでおくのは、他の関数を書くときの印刷やデバッグを容易にするためです。
効果を見てみましょう:
連絡先の検索、削除、および変更の最初のステップは、連絡先を見つけることです。これにより、連絡先を一斉に見つける関数を作成できます。
static int FindName(struct Contact* pc, char name[MAX_NAME])
{
int i;
for (i = 0; i < pc->size; i++)
{
if (0 == strcmp(pc->data[i].name, name))
{
return i;
}
}
return -1;
}
ループを使用してトラバースし、見つかった場合は i、つまり連絡先のストレージ番号を返し、見つからない場合は -1 を返します
2 番目の項目を完了する: 連絡先を削除する
void DelContact(struct Contact* pc)
{
int poc;
char name[MAX_NAME];
printf("请输入你要删除的对象名字->");
scanf("%s", &name);
//对定位函数的使用
poc = FindName(pc, name);
if (poc == -1)
{
printf("你要删除的对象不在。");
}
else {
for (int j = poc; j < pc->size - 1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->size--;
printf("删除成功!\n");
}
}
連絡先のサイズを小さくする - 1 回
効果を見てみましょう:
完成品 3: 連絡先を探す
void SaerchContact(struct Contact* pc)
{
int poc;
char name[MAX_NAME];
printf("请输入你要查找的对象名字->");
scanf("%s", &name);
//对定位函数的使用
poc = FindName(pc, name);
if (poc == -1)
{
printf("你要查找的对象不在。");
}
else {
printf("名字: ");
printf("%-20s\n", pc->data[poc].name);
printf("年龄: ");
printf("%-4d\n", (pc->data[poc].age));
printf("性别: ");
printf("%-5s\n", pc->data[poc].sec);
printf("电话: ");
printf("%-12s\n", pc->data[poc].tele);
printf("地址: ");
printf("%-30s\n", pc->data[poc].addr);
}
}
連絡先を検索する機能の原則は、検索して印刷することです。
効果を見てみましょう:
4 番目の項目を完了する: 連絡先の変更
void ModContact(struct Contact* pc)
{
int poc;
char name[MAX_NAME];
printf("请输入你要修改的对象->");
scanf("%s", &name);
//对定位函数的使用
poc = FindName(pc, name);
if (poc == -1)
{
printf("你要修改的对象不在。");
}
else {
printf("请输入名字->");
scanf("%s", pc->data[poc].name);
printf("请输入年龄->");
scanf("%d", &(pc->data[poc].age));
printf("请输入性别->");
scanf("%s", pc->data[poc].sec);
printf("请输入电话->");
scanf("%s", pc->data[poc].tele);
getchar();
printf("请输入地址->");
scanf("%s", pc->data[poc].addr);
getchar();
printf("修改完成!");
}
}
接点を変更する機能を使用する原則は、配置して追加することですが、サイズは変わらないことに注意してください。
効果を見てみましょう:
ファイル内の結果を見てみましょう
暗号化。
家族の皆さん、ここに来て、あなたの小さな手を使って金持ちになり、私のように少し注目してください。あなたのサポートが私の創造の原動力です。誰もが一緒に学べる高品質の記事を引き続き公開します。