通訊錄初階: 點(diǎn)這里
通訊錄中階: 點(diǎn)這里
文件管理版本改進(jìn)之處
通訊錄初始化
contact.c
退出通訊錄并保存
test.c
contact.c
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-580692.html
contact.h
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-580692.html
完整代碼
contact.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX_CONTACT 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
//動(dòng)態(tài)版本
#define DEFAULT_SIZE 3
#define INC_SIZE 2
enum OPTION
{
EXIT0,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
enum Peo
{
EXIT1,
NAME,
AGE,
SEX,
TELE,
ADDR
};
//一個(gè)人信息的結(jié)構(gòu)體
typedef struct People
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
}Peo;
//存放大量人信息的通訊錄
// 靜態(tài)版本
//typedef struct Contact
//{
// Peo data[MAX_CONTACT];
// int sz;
//}Con;
//動(dòng)態(tài)版本
//最初容量設(shè)置為3,當(dāng)放滿之后每次動(dòng)態(tài)開辟2個(gè)容量
typedef struct Contact
{
Peo* data;//指向存放數(shù)據(jù)的空間
int sz;//記錄當(dāng)前通訊錄有效元素的個(gè)數(shù)
int capacity;//通訊錄當(dāng)前最大容量
}Con;
//初始化通訊錄
void InitContact(Con* pc);
//給通訊錄添加聯(lián)系人
void AddContact(Con* pc);
//顯示通訊錄信息
void ShowContact(const Con* pc);
//刪除指定聯(lián)系人
void DelContact(Con* pc);
//查找指定聯(lián)系人
void SearchContact(const Con* pc);
//修改指定聯(lián)系人的信息
void ModifyContact(Con* pc);
//按照指定方式排序
void SortContact(Con* pc);
//文件版本
//把通訊錄保存到文件中
void SaveContact(Con* pc);
//動(dòng)態(tài)版本
//銷毀通訊錄
void DestroyContact(Con* pc);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
//初始化通訊錄——————————————————————————————————————————————————————————
//靜態(tài)版本
//void InitContact(Con* pc)
//{
// assert(pc);
//
// //循環(huán)初始化也可
// //int i = 0;
// //for (i = 0; i < MAX_CONTACT; i++)
// //{
// // strcpy(pc->data[i].name, "0");
// // pc->data[i].age = 0;
// // strcpy(pc->data[i].sex, "0");
// // strcpy(pc->data[i].tele, "0");
// // strcpy(pc->data[i].addr, "0");
// //}
// //pc->sz = 0;
//
// //初始化結(jié)構(gòu)體數(shù)組最簡(jiǎn)單的方法
// memset(pc->data, 0, sizeof(pc->data));
// pc->sz = 0;
//}
//動(dòng)態(tài)版本
//void InitContact(Con* pc)
//{
// assert(pc);
//
// pc->data = (Peo*)malloc(DEFAULT_SIZE * sizeof(Peo));
// if (pc->data == NULL)
// {
// perror(InitContact);
// return;
// }
// pc->sz = 0;
// pc->capacity = DEFAULT_SIZE;
//}
//文件版本
static int CheckCapacity(Con* pc)
{
if (pc->sz == pc->capacity)
{
Peo* ptr = realloc(pc->data, (pc->capacity + INC_SIZE) * sizeof(Peo));
if (ptr == NULL)
{
perror("CheakCapacity");
return 0;
}
else
{
pc->data = ptr;
pc->capacity += INC_SIZE;
return 1;
}
}
return 1;
}
static void LoadContact(Con* pc)
{
//打開文件
FILE* pf = fopen("contact.dat", "rb");
if (pf == NULL)
{
perror("LoadContact");
return;
}
//讀文件
Peo tmp = { 0 };
while (fread(&tmp, sizeof(Peo), 1, pf))
{
if (0 == CheckCapacity(pc))
{
return;
}
pc->data[pc->sz] = tmp;
pc->sz++;
}
//關(guān)閉文件
fclose(pf);
pf = NULL;
}
void InitContact(Con* pc)
{
assert(pc);
pc->data = (Peo*)malloc(DEFAULT_SIZE * sizeof(Peo));
if (pc->data == NULL)
{
perror(InitContact);
return;
}
pc->sz = 0;
pc->capacity = DEFAULT_SIZE;
//文件中保存的信息加載到通訊錄中
LoadContact(pc);
}
//給通訊錄添加聯(lián)系人——————————————————————————————————————————————————————
//void AddContact(Con* pc)
//{
// assert(pc);
//
// if (pc->sz == MAX_CONTACT)
// {
// printf("通訊錄已滿,無(wú)法添加\n");
// return;
// }
//
// printf("請(qǐng)輸入名字:>");
// scanf("%s", pc->data[pc->sz].name);
// printf("請(qǐng)輸入年齡:>");
// scanf("%d", &(pc->data[pc->sz].age));
// printf("請(qǐng)輸入性別:>");
// scanf("%s", pc->data[pc->sz].sex);
// printf("請(qǐng)輸入電話:>");
// scanf("%s", pc->data[pc->sz].tele);
// printf("請(qǐng)輸入地址:>");
// scanf("%s", pc->data[pc->sz].addr);
//
// pc->sz++;
// printf("增加聯(lián)系人成功\n");
//}
//動(dòng)態(tài)版本
void AddContact(Con* pc)
{
assert(pc);
if (0 == CheckCapacity(pc))
{
return;
}
printf("請(qǐng)輸入名字:>");
scanf("%s", pc->data[pc->sz].name);
printf("請(qǐng)輸入年齡:>");
scanf("%d", &(pc->data[pc->sz].age));
printf("請(qǐng)輸入性別:>");
scanf("%s", pc->data[pc->sz].sex);
printf("請(qǐng)輸入電話:>");
scanf("%s", pc->data[pc->sz].tele);
printf("請(qǐng)輸入地址:>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("增加聯(lián)系人成功\n");
}
//顯示通訊錄信息——————————————————————————————————————————————————————————
void ShowContact(const Con* pc)
{
assert(pc);
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年齡", "性別", "電話", "地址");
int i = 0;//如果后面需要i的值,就不能定義在for循環(huán)的初始化部分,因?yàn)槌隽搜h(huán)就被銷毀
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
//刪除指定聯(lián)系人——————————————————————————————————————————————————————————
static int FindByName(const Con* pc, char* name)
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
void DelContact(Con* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("通訊錄為空\(chéng)n");
return;
}
char name[MAX_NAME] = { 0 };
printf("請(qǐng)輸入要?jiǎng)h除的人的名字:>");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要?jiǎng)h除的人不存在\n");
return;
}
//刪除方法一:從后向前一個(gè)個(gè)覆蓋
//for (i = pos; i < pc->sz - 1; i++)
//{
// pc->data[i] = pc->data[i + 1];
//}
//pc->sz--;
//刪除方法二:memmove,和方法一相同
//memmove(&(pc->data[pos]), &(pc->data[pos + 1]), ((pc->sz) - pos - 1) * (sizeof(pc->data[0])));
//pc->sz--;
//刪除方法三:將要?jiǎng)h除的和最后一個(gè)交換,然后sz--
Peo tmp = pc->data[pos];
pc->data[pos] = pc->data[pc->sz - 1];
pc->data[pc->sz - 1] = tmp;
pc->sz--;
printf("刪除聯(lián)系人成功\n");
}
//查找指定聯(lián)系人————————————————————————————————————————————————————————————
void SearchContact(const Con* pc)
{
assert(pc);
//學(xué)習(xí)c++之后可以用函數(shù)重載實(shí)現(xiàn)用任何信息都能進(jìn)行檢索
char name[MAX_NAME] = { 0 };
printf("請(qǐng)輸入要查找人的名字:>");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
}
else
{
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年齡", "性別", "電話", "地址");
printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
}
//修改指定聯(lián)系人的信息——————————————————————————————————————————————————————
void ModifyContact(Con* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("請(qǐng)輸入要修改人的名字:>");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要修改的人不存在");
}
else
{
//一股腦修改全部信息
//printf("請(qǐng)輸入名字:>");
//scanf("%s", pc->data[pos].name);
//printf("請(qǐng)輸入年齡:>");
//scanf("%d", &(pc->data[pos].age));
//printf("請(qǐng)輸入性別:>");
//scanf("%s", pc->data[pos].sex);
//printf("請(qǐng)輸入電話:>");
//scanf("%s", pc->data[pos].tele);
//printf("請(qǐng)輸入地址:>");
//scanf("%s", pc->data[pos].addr);
//printf("修改成功\n");
//結(jié)合switch指定修改某個(gè)信息
int input = 0;
do
{
printf("0.EXIT1 1.NAME 2.AGE 3.SEX 4.TELE 5.ADDR\n");
printf("請(qǐng)選擇要修改的信息or選擇0退出修改:>");
scanf("%d", &input);
switch (input)
{
case NAME:
printf("請(qǐng)輸入修改后的名字:>");
scanf("%s", pc->data[pos].name);
break;
case AGE:
printf("請(qǐng)輸入修改后的年齡:>");
scanf("%d", &(pc->data[pos].age));
break;
case SEX:
printf("請(qǐng)輸入修改后的性別:>");
scanf("%s", pc->data[pos].sex);
break;
case TELE:
printf("請(qǐng)輸入修改后的電話:>");
scanf("%s", pc->data[pos].tele);
break;
case ADDR:
printf("請(qǐng)輸入修改后的地址:>");
scanf("%s", pc->data[pos].addr);
break;
case EXIT1:
break;
default:
printf("選擇錯(cuò)誤,重新選擇\n");
break;
}
} while (input);
printf("修改成功\n");
}
}
//按照指定方式排序——————————————————————————————————————————————————————————————
int flag = 0;//qsort和Cmp函數(shù)已經(jīng)固定好參數(shù),要想體現(xiàn)升序和降序,只能定義全局變量,然后在函數(shù)里調(diào)用
static int CmpCharArr(const void* p1, const void* p2)
{
return flag * (strcmp((*(Peo*)p1).name, (*(Peo*)p2).name));
}
static int CmpInt(const void* p1, const void* p2)
{
return flag * (((*(Peo*)p1).age) - ((*(Peo*)p2).age));
}
void SortContact(Con* pc)
{
assert(pc);
int input = 0;
do
{
printf("0.EXIT1 1.NAME 2.AGE 3.SEX 4.TELE 5.ADDR\n");
printf("請(qǐng)選擇要按照哪種方式排序or選擇0退出排序:>");
scanf("%d", &input);
if (input != 0)
{
printf("升序選擇1,降序選擇-1:>");
while (flag != 1 && flag != -1)
{
scanf("%d", &flag);
if (flag != 1 && flag != -1)
{
printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
}
}
}
switch (input)
{
case NAME:
qsort(pc, pc->sz, sizeof(pc->data[0]), CmpCharArr);
printf("排序成功\n");
break;
case AGE:
qsort(pc, pc->sz, sizeof(pc->data[0]), CmpInt);
printf("排序成功\n");
break;
case SEX:
qsort(pc, pc->sz, sizeof(pc->data[0]), CmpCharArr);
printf("排序成功\n");
break;
case TELE:
qsort(pc, pc->sz, sizeof(pc->data[0]), CmpCharArr);
printf("排序成功\n");
break;
case ADDR:
qsort(pc, pc->sz, sizeof(pc->data[0]), CmpCharArr);
printf("排序成功\n");
break;
case EXIT1:
break;
default:
printf("選擇錯(cuò)誤,重新選擇\n");
break;
}
} while (input);
}
//文件版本
void SaveContact(Con* pc)
{
FILE* pf = fopen("contact.dat", "wb");
if (pf == NULL)
{
perror("SaveContact");
return;
}
//寫數(shù)據(jù)
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(Peo), 1, pf);
}
//關(guān)閉文件
fclose(pf);
pf = NULL;
}
//動(dòng)態(tài)版本
void DestroyContact(Con* pc)
{
free(pc->data);
pc->data = NULL;
pc->capacity = pc->sz = 0;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("*******1.ADD 2.DEL *****\n");
printf("*******3.SEARCH 4.MODIFY*****\n");
printf("*******5.SHOW 6.SORT *****\n");
printf("*******0.EXIT *****\n");
printf("********************************\n");
}
void test()
{
int input = 0;
Con con;
InitContact(&con);
do
{
menu();
printf("請(qǐng)選擇:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
//c++要是有函數(shù)重載會(huì)好寫很多
SortContact(&con);
break;
case EXIT0:
//文件版本
SaveContact(&con);
//動(dòng)態(tài)版本
DestroyContact(&con);
printf("退出通訊錄\n");
break;
default:
printf("選擇錯(cuò)誤,重新選擇\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
到了這里,關(guān)于C語(yǔ)言小項(xiàng)目——通訊錄高階(文件管理版)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!