C语言课设——通讯录(静态、动态、文件三版合一)(下)

简介: 下面是不同版本的源码,文件版为重新编写的版本,在部分变量和函数命名上可能与前两个版本有差异,但底层逻辑是一致的。

下面是不同版本的源码,文件版为重新编写的版本,在部分变量和函数命名上可能与前两个版本有差异,但底层逻辑是一致的。


🌲静态版

🌱Contacts.h 功能声明头文件

#pragma once#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>#include<windows.h>#define MAX 100#define MAX_NAME 10#define MAX_SEX 5#define MAX_NUMBER 15#define MAX_ADDRESS 30//联系人信息structPeoInfo{
charname[MAX_NAME];
charsex[MAX_SEX];
intage;
charnumber[MAX_NUMBER];
charaddress[MAX_ADDRESS];
};
//包含下标的信息typedefstructContact{
structPeoInfodata[MAX];
intsz;
}Con;
voidConInit(Con*pc);//初始化通讯录voidConPrint(constCon*pc);//打印通讯录voidConAdd(Con*pc);//增加信息voidConErase(Con*pc);//删除信息voidConFind(constCon*pc);//查找信息voidConRevise(Con*pc);//修改信息voidConEraseAll(Con*pc);//全部删除voidConSortByName(Con*pc);//按名字排序

🌱Contacts.c 功能实现源文件

#define _CRT_SECURE_NO_WARNINGS 1#include"Contact.h"staticvoidmenu()
{
printf("*******************************\n");
printf("******1.Name     2.Age   ******\n");
printf("******3.Sex      4.Number******\n");
printf("******5.Address  6.Exit  ******\n");
printf("*******************************\n");
}
voidConInit(Con*pc)//初始化通讯录{
assert(pc);
pc->sz=0;//下标归零memset(pc->data, 0, sizeof(structPeoInfo) *MAX);//内存设置,初始化}
voidConPrint(constCon*pc)//打印通讯录{
assert(pc);
if (pc->sz==0)
    {
printf("当前通讯录为空,请尝试添加联系人!\n");
return;
    }
inti=0;
//经测试,发现使用宏定义的常量,如 MAX_NAME 代替 10,打印会出错printf("%-10s\t%-5s\t%-s\t%-15s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
for (i=0; i<pc->sz; i++)
    {
printf("%-10s\t%-5s\t%-d\t%-15s\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].number, pc->data[i].address);
    }
}
voidConAdd(Con*pc)//增加信息{
assert(pc);
if (pc->sz==MAX)
    {
printf("内存已满,请尝试删除部分联系人!\n");
return;
    }
//逐个输入printf("请输入姓名:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入号码:>");
scanf("%s", pc->data[pc->sz].number);
printf("请输入住址:>");
scanf("%s", pc->data[pc->sz].address);
pc->sz++;//每添加一条信息,长度就+1printf("增加成功!\n");
}
staticintFind(constCon*pc, constchar*name)//辅助查找函数{
assert(pc);
inti=0;
for (i=0; i<pc->sz; i++)
    {
if (strcmp(name, pc->data[i].name) ==0)
returni;//返回下标    }
return-1;//没有找到}
voidConErase(Con*pc)//删除信息{
assert(pc);
if (!(pc->sz))
    {
printf("当前通讯录为空,请尝试添加联系人!\n");
return;
    }
charname[MAX_NAME] ="0";//临时存储待查找姓名printf("请输入你想删除联系人的姓名:>");
scanf("%s", name);
if (Find(pc, name) ==-1)
    {
printf("没有找到此联系人!\n");
    }
else    {
inti=Find(pc, name);
for (; i<pc->sz-1; i++)
        {
pc->data[i] =pc->data[i+1];
        }
pc->sz--;//删除完后,长度-1printf("删除成功!\n");
    }
}
voidConFind(constCon*pc)//查找信息{
assert(pc);
printf("请输入你想查找联系人的姓名:>");
charname[MAX_NAME] ="0";//临时存储待查找姓名scanf("%s", name);
intret=Find(pc, name);//判断变量if (ret==-1)
    {
printf("没有找到这个联系人!\n");
    }
else    {
printf("此联系人信息如下:\n\n");
printf("%-10s\t%-5s\t%-s\t%-15s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
printf("%-10s\t%-5s\t%-d\t%-15s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
pc->data[ret].number, pc->data[ret].address);
    }
}
voidConRevise(Con*pc)//修改信息{
assert(pc);
charname[MAX_NAME] ="0";//存储查找人的姓名printf("请输入你想修改联系人的姓名:>");
scanf("%s", name);
intret=Find(pc, name);//判断变量if (ret==-1)
    {
printf("没有找到这个联系人!\n");
    }
else    {
intinput=0;
menu();//菜单,不同于主函数中的menuprintf("请选择你想修改的信息:>");
scanf("%d", &input);
//分类讨论,本来想再封装一个函数,考虑到每次修改内容都不同//就没有设计了switch (input)
        {
case1:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].name);
printf("修改成功!\n");
break;
case2:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].sex);
printf("修改成功!\n");
break;
case3:
printf("请输入你想修改的值:>");
scanf("%d", &(pc->data[ret].age));
printf("修改成功!\n");
break;
case4:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].number);
printf("修改成功!\n");
break;
case5:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].address);
printf("修改成功!\n");
break;
case0:
printf("中止修改!\n");
break;
default:
printf("选择有误!\n");
break;
        }
    }
}
voidConEraseAll(Con*pc)//全部删除{
assert(pc);
ConInit(pc);//直接初始化,就是全部删除printf("通讯录中的所有信息都已重置!\n");
}
staticintcmp(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->name, ((structPeoInfo*)e2)->name);
}
voidConSortByName(Con*pc)//按名字排序{
assert(pc);
if (pc->sz==0)
    {
printf("当前通讯录为空,无法排序!\n");
return;
    }
else    {
qsort(pc, pc->sz, sizeof(structPeoInfo), cmp);//快速排序//出现bug,原因快排设计大小为char,与类型不匹配printf("排序已完成,信息如下:>\n\n");
ConPrint(pc);
    }
}


🌱test.c         主函数源文件

#define _CRT_SECURE_NO_WARNINGS 1//实现通讯录#include"Contact.h"//第一代通讯录,无bug//刷新git提交voidmenu()
{
printf("******   通讯录 1.0   ********\n");
printf("******************************\n");
printf("******1.Add     2.Del   ******\n");
printf("******3.Find    4.Revise******\n");
printf("******5.Show    6.Empty ******\n");
printf("******7.Sort    0.Exit  ******\n");
printf("******************************\n");
}
intmain()
{
ConC;
ConInit(&C);
intinput=0;
do    {
menu();
printf("请选择:>");
scanf("%d", &input);
system("cls");
switch (input)
        {
case1:
ConAdd(&C);
break;
case2:
ConErase(&C);
break;
case3:
ConFind(&C);
break;
case4:
ConRevise(&C);
break;
case5:
ConPrint(&C);
break;
case6:
ConEraseAll(&C);
break;
case7:
ConSortByName(&C);
break;
case0:
printf("退出通讯录!\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
        }
    } while (input);
return0;
}


🌲动态版

🌱Contacts.h 功能声明头文件

#pragma once#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>#include<windows.h>#define MAX 100#define MAX_NAME 10#define MAX_SEX 5#define MAX_NUMBER 15#define MAX_ADDRESS 30#define DEFAULT_SIZE 2#define INC_SZ 2//联系人信息structPeoInfo{
charname[MAX_NAME];
charsex[MAX_SEX];
intage;
charnumber[MAX_NUMBER];
charaddress[MAX_ADDRESS];
};
typedefstructContact{
structPeoInfo*data;
intsz;//下标intcapacity;//容量}Con;
voidConInit(Con*pc);//初始化通讯录voidConPrint(constCon*pc);//打印通讯录voidConAdd(Con*pc);//增加信息voidConErase(Con*pc);//删除信息voidConFind(constCon*pc);//查找信息voidConRevise(Con*pc);//修改信息voidConEraseAll(Con*pc);//全部删除voidConSortByName(Con*pc);//按名字排序voidConDestroy(Con*pc);//销毁通讯录

🌱Contacts.c 功能实现源文件

#define _CRT_SECURE_NO_WARNINGS 1#include"Contacts.h"staticvoidmenu()
{
printf("*******************************\n");
printf("******1.Name     2.Sex   ******\n");
printf("******3.Age      4.Number******\n");
printf("******5.Address  0.Exit  ******\n");
printf("*******************************\n");
}
enumMenu{
Exit,
Name,
Sex,
Age,
Number,
Address};
voidConInit(Con*pc)//初始化通讯录{
assert(pc);
pc->data= (structPeoInfo*)malloc(sizeof(structPeoInfo) *DEFAULT_SIZE);
if (pc->data==NULL)
    {
perror("ConInit");
return;
    }
pc->sz=0;//下标归零pc->capacity=DEFAULT_SIZE;//容量归0}
voidConPrint(constCon*pc)//打印通讯录{
assert(pc);
if (pc->sz==0)
    {
printf("当前通讯录为空,请尝试添加联系人!\n");
return;
    }
inti=0;
//经测试,发现使用宏定义的常量,如 MAX_NAME 代替 10,打印会出错printf("%-10s\t%-5s\t%-s\t%-15s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
for (i=0; i<pc->sz; i++)
    {
printf("%-10s\t%-5s\t%-d\t%-15s\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].number, pc->data[i].address);
    }
}
voidcheckCapacity(Con*pc)
{
intnewCapacity= (pc->capacity) *INC_SZ;
structPeoInfo*ret= (structPeoInfo*)realloc(pc->data, sizeof(structPeoInfo) *newCapacity);
assert(ret);
pc->capacity=newCapacity;
pc->data=ret;
printf("增容成功!\n");
}
voidConAdd(Con*pc)//增加信息{
assert(pc);
if (pc->sz==pc->capacity)
checkCapacity(pc);
//逐个输入printf("请输入姓名:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入号码:>");
scanf("%s", pc->data[pc->sz].number);
printf("请输入住址:>");
scanf("%s", pc->data[pc->sz].address);
pc->sz++;//每添加一条信息,长度就+1printf("增加成功!\n");
}
staticintFind(constCon*pc, constchar*name)//辅助查找函数{
assert(pc);
inti=0;
for (i=0; i<pc->sz; i++)
    {
if (strcmp(name, pc->data[i].name) ==0)
returni;//返回下标    }
return-1;//没有找到}
voidConErase(Con*pc)//删除信息{
assert(pc);
if (!(pc->sz))
    {
printf("当前通讯录为空,请尝试添加联系人!\n");
return;
    }
charname[MAX_NAME] ="0";//临时存储待查找姓名printf("请输入你想删除联系人的姓名:>");
scanf("%s", name);
if (Find(pc, name) ==-1)
    {
printf("没有找到此联系人!\n");
    }
else    {
inti=Find(pc, name);
for (; i<pc->sz-1; i++)
        {
pc->data[i] =pc->data[i+1];
        }
pc->sz--;//删除完后,长度-1printf("删除成功!\n");
    }
}
voidConFind(constCon*pc)//查找信息{
assert(pc);
printf("请输入你想查找联系人的姓名:>");
charname[MAX_NAME] ="0";//临时存储待查找姓名scanf("%s", name);
intret=Find(pc, name);//判断变量if (ret==-1)
    {
printf("没有找到这个联系人!\n");
    }
else    {
printf("此联系人信息如下:\n\n");
printf("%-10s\t%-5s\t%-s\t%-15s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
printf("%-10s\t%-5s\t%-d\t%-15s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
pc->data[ret].number, pc->data[ret].address);
    }
}
voidConRevise(Con*pc)//修改信息{
assert(pc);
charname[MAX_NAME] ="0";//存储查找人的姓名printf("请输入你想修改联系人的姓名:>");
scanf("%s", name);
intret=Find(pc, name);//判断变量if (ret==-1)
    {
printf("没有找到这个联系人!\n");
    }
else    {
intinput=0;
menu();//菜单,不同于主函数中的menuprintf("请选择你想修改的信息:>");
scanf("%d", &input);
//分类讨论,本来想再封装一个函数,考虑到每次修改内容都不同//就没有设计了switch (input)
        {
caseName:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].name);
printf("修改成功!\n");
break;
caseSex:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].sex);
printf("修改成功!\n");
break;
caseAge:
printf("请输入你想修改的值:>");
scanf("%d", &(pc->data[ret].age));
printf("修改成功!\n");
break;
caseNumber:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].number);
printf("修改成功!\n");
break;
caseAddress:
printf("请输入你想修改的值:>");
scanf("%s", pc->data[ret].address);
printf("修改成功!\n");
break;
caseExit:
printf("中止修改!\n");
break;
default:
printf("选择有误!\n");
break;
        }
    }
}
voidConEraseAll(Con*pc)//全部删除{
assert(pc);
ConInit(pc);//直接初始化,就是全部删除printf("通讯录中的所有信息都已重置!\n");
}
staticintcmp(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->name, ((structPeoInfo*)e2)->name);
}
voidConSortByName(Con*pc)//按名字排序{
assert(pc);
if (pc->sz==0)
    {
printf("当前通讯录为空,无法排序!\n");
return;
    }
else    {
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmp);//快速排序//出现bug,原因快排设计大小为char,与类型不匹配//*bug已解决,排序已全面推广printf("排序已完成,信息如下:>\n\n");
ConPrint(pc);
    }
}
voidConDestroy(Con*pc)//销毁通讯录{
assert(pc);
free(pc->data);
pc->data=NULL;
pc->sz=pc->capacity=0;
}


🌱test.c         主函数源文件


#define _CRT_SECURE_NO_WARNINGS 1//实现通讯录#include"Contacts.h"//9_25 进行改造,改为动态版本voidmenu()
{
printf("******************************\n");
printf("******1.Add     2.Del   ******\n");
printf("******3.Find    4.Revise******\n");
printf("******5.Show    6.Empty ******\n");
printf("******7.Sort    0.Exit  ******\n");
printf("******************************\n");
}
enumMenu{
Exit,
Add,
Del,
Find,
Revise,
Show,
Empty,
Sort};
intmain()
{
ConC;
ConInit(&C);
intinput=0;
do    {
menu();
printf("请选择:>");
scanf("%d", &input);
system("cls");
switch (input)
        {
caseAdd:
ConAdd(&C);
break;
caseDel:
ConErase(&C);
break;
caseFind:
ConFind(&C);
break;
caseRevise:
ConRevise(&C);
break;
caseShow:
ConPrint(&C);
break;
caseEmpty:
ConEraseAll(&C);
break;
caseSort:
ConSortByName(&C);
break;
caseExit:
printf("退出通讯录!\n");
ConDestroy(&C);
break;
default:
printf("选择错误,请重新选择!\n");
break;
        }
    } while (input);
return0;
}


🌲文件操作版

🌱Contacts.h 功能声明头文件

#pragma once#include<stdio.h>#include<stdlib.h>#include<windows.h>#include<assert.h>#define DEFAULT_SIZE 3 //默认通讯录大小为3,如果不够用,会扩容#define INC_SZ 2 * DEFAULT_SIZE //每次扩容两倍#define MAX_NAME 10#define MAX_SEX 5#define MAX_NUMBER 20#define MAX_ADDRESS 50structPeoInfo{
charname[MAX_NAME];//姓名charsex[MAX_SEX];//性别intage;//年龄charnumber[MAX_NUMBER];//电话号码charaddress[MAX_ADDRESS];//住址};
typedefstructContactByPeo{
structPeoInfo*data;//数据域intsz;//下标intcapacity;//容量}Con;
voidConInit(Con*pc);//初始化通讯录voidConDisplay(constCon*pc);//打印通讯录voidConDestroy(Con*pc);//销毁通讯录//增删查改排voidConAdd(Con*pc);//增加联系人信息voidConDelte(Con*pc);//删除联系人信息voidConFind(constCon*pc);//查找联系人信息voidConRevise(Con*pc);//修改联系人信息voidConSort(Con*pc);//对信息进行排序intConInfoNum(constCon*pc);//统计通讯录中的信息数voidConLoad(Con*pc);//加载通讯录信息voidConSave(Con*pc);//通讯录信息保存

🌱Contacts.c 功能实现源文件

#define _CRT_SECURE_NO_WARNINGS 1   #include"Contact.h"voidbuyNewCapacity(Con*pc);//声明扩容函数voidConLoad(Con*pc);//声明 加载通讯录信息voidConInit(Con*pc)//初始化通讯录{
assert(pc);
pc->data= (structPeoInfo*)malloc(sizeof(structPeoInfo) *DEFAULT_SIZE);
if (NULL==pc->data)
    {
//申请失败,终止初始化perror("malloc");
return;
    }
pc->sz=0;//下标为0pc->capacity=DEFAULT_SIZE;//确定容量ConLoad(pc);//加载通讯录}
voidConDisplay(constCon*pc)//打印通讯录{
assert(pc);
if (pc->sz==0)
    {
printf("当前通讯录为空,请尝试添加联系人!\n");
return;
    }
printf("%-10s\t%-5s\t%-s\t%-20s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
inti=0;
for (i=0; i<pc->sz; i++)
    {
printf("%-10s\t%-5s\t%-d\t%-20s\t%-30s\n", pc->data[i].name, pc->data[i].sex, 
pc->data[i].age, pc->data[i].number, pc->data[i].address);
    }
}
voidConDestroy(Con*pc)//销毁通讯录{
assert(pc);
free(pc->data);
pc->data=NULL;
pc->sz=pc->capacity=0;
}
//扩容函数,如果下标碰到容量了,就需要扩容voidbuyNewCapacity(Con*pc)
{
assert(pc);
structPeoInfo*ret= (structPeoInfo*)realloc(pc->data, sizeof(structPeoInfo) *INC_SZ);
if (NULL==ret)
    {
//申请失败perror("relloc");
return;
    }
pc->data=ret;
pc->capacity+=INC_SZ;//容量增加}
//增删查改排voidConAdd(Con*pc)//增加联系人信息{
assert(pc);
if (pc->capacity==pc->sz)
buyNewCapacity(pc);//容量不足就扩容printf("请输入姓名:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].number);
printf("请输入住址:>");
scanf("%s", pc->data[pc->sz].address);
printf("信息增加完毕!\n");
pc->sz++;
}
constintfindByName(constCon*pc)//只允许在这个文件内使用{
assert(pc);
charfindName[MAX_NAME] ="0";
printf("请输入想查找的联系人姓名:>");
scanf("%s", findName);
inti=0;
for (i=0; i<pc->sz; i++)
    {
if (strcmp(pc->data[i].name, findName) ==0)
returni;
    }
return-1;
}
voidConDelte(Con*pc)//删除联系人信息{
assert(pc);
intret=findByName(pc);//顺序表,可以返回下标if (ret>=0)
    {
intinput=0;
printf("确认删除此人信息吗?取消输入0,否则输入任意数:>");
scanf("%d", &input);
if (input==0)
        {
printf("取消成功!\n");
return;
        }
printf("正在删除中…………\n");
Sleep(1500);
inti=ret;
for (; i<pc->sz; i++)
pc->data[i] =pc->data[i+1];
pc->sz--;
printf("删除完成!\n");
    }
elseprintf("查无此人!\n");
}
voidDisplayByRet(constCon*pc, intret)
{
assert(pc);
printf("已经找到这个人了,信息如下所示:\n");
printf("%-10s\t%-5s\t%-s\t%-20s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");
printf("%-10s\t%-5s\t%-d\t%-20s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,
pc->data[ret].age, pc->data[ret].number, pc->data[ret].address);
}
voidConFind(constCon*pc)//查找联系人信息{
assert(pc);
intret=findByName(pc);
if (ret>=0)
    {
DisplayByRet(pc, ret);
return;
    }
elseprintf("查无此人!\n");
}
//服务于修改的菜单voidmenuByReviseAndSort()
{
printf("***************************************\n");
printf("**********  0.终止  1.姓名  **********\n");
printf("**********  2.性别  3.年龄  **********\n");
printf("**********  4.电话  5.住址  **********\n");
printf("***************************************\n");
}
enumMenuByReviseAndSort{
终止,姓名, 性别, 年龄, 电话, 住址};
voidConRevise(Con*pc)//修改联系人信息{
assert(pc);
//因为待修改的信息,有共同特征,因此可以用宏定义来实现intret=findByName(pc);
if (ret>=0)
    {
DisplayByRet(pc, ret);
intinput=1;
while (input)
        {
menuByReviseAndSort();
printf("请选择你想修改的信息:>");
scanf("%d", &input);
switch (input)
            {
case终止:
printf("终止修改成功!\n");
break;
case姓名:
printf("请输入修改后的信息:>");
scanf("%s", pc->data[ret].name);
printf("修改成功!\n");
break;
case性别:
printf("请输入修改后的信息:>");
scanf("%s", pc->data[ret].sex);
printf("修改成功!\n");
break;
case年龄:
printf("请输入修改后的信息:>");
scanf("%d", &(pc->data[ret].age));
printf("修改成功!\n");
break;
case电话:
printf("请输入修改后的信息:>");
scanf("%s", pc->data[ret].number);
printf("修改成功!\n");
break;
case住址:
printf("请输入修改后的信息:>");
scanf("%s", pc->data[ret].address);
printf("修改成功!\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
            }
        }
    }
elseprintf("查无此人!\n");
}
//各种排序的比较函数intcmpByName(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->name, ((structPeoInfo*)e2)->name);    //按姓名}
intcmpBySex(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->sex, ((structPeoInfo*)e2)->sex);  //按性别}
intcmpByAge(constvoid*e1, constvoid*e2)
{
return (((structPeoInfo*)e1)->age) - (((structPeoInfo*)e2)->age); //按年龄}
intcmpByNumber(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->number, ((structPeoInfo*)e2)->number);    //按电话号码}
intcmpByAddress(constvoid*e1, constvoid*e2)
{
returnstrcmp(((structPeoInfo*)e1)->address, ((structPeoInfo*)e2)->address);  //按地址}
voidConSort(Con*pc)//对信息进行排序{
assert(pc);
intinput=1;
while (input)
    {
menuByReviseAndSort();
printf("选择排序方式:>");
scanf("%d", &input);
switch (input)
        {
case终止:
printf("终止排序成功!\n");
break;
case姓名:
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmpByName);
printf("按性别排序已经完成了,信息如下:\n");
ConDisplay(pc);
break;
case性别:
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmpBySex);
printf("按性别排序已经完成了,信息如下:\n");
ConDisplay(pc);
break;
case年龄:
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmpByAge);
printf("按年龄排序已经完成了,信息如下:\n");
ConDisplay(pc);
break;
case电话:
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmpByNumber);
printf("按电话排序已经完成了,信息如下:\n");
ConDisplay(pc);
break;
case住址:
qsort(pc->data, pc->sz, sizeof(structPeoInfo), cmpByAddress);
printf("按住址排序已经完成了,信息如下:\n");
ConDisplay(pc);
break;
default:
printf("选择错误,请重新选择!\n");
break;
        }
    }
}
intConInfoNum(constCon*pc)//统计通讯录中的信息数{
assert(pc);
returnpc->sz;
}
voidConLoad(Con*pc)//加载通讯录信息{
assert(pc);
FILE*fp=fopen("Contact.txt", "r");//打开文件if (NULL==fp)
    {
perror("fopen::Contact.txt");
return;
    }
//读数据structPeoInfotmp= { 0 };//临时存储intret=0;
charch[10] ="0";
fscanf(fp, "%s %s %s %s %s", ch, ch, ch, ch, ch);
while (ret= (fscanf(fp, "%s %s %d %s %s", tmp.name, tmp.sex, 
&(tmp.age), tmp.number, tmp.address)) >=1)
    {
if (pc->sz==pc->capacity)
buyNewCapacity(pc);//扩容pc->data[pc->sz] =tmp;
pc->sz++;
    }
if (feof(fp))
printf("\nEnd by EOF\n");
elseif (ferror(fp))
printf("\nEnd by IO\n");
//关闭文件fclose(fp);
fp=NULL;
}
voidConSave(Con*pc)//通讯录信息保存{
assert(pc);
FILE*fp=fopen("Contact.txt", "w");//打开文件if (NULL==fp)
    {
perror("fopen::Contact.txt");
return;
    }
//写文件fprintf(fp, "%-10s\t%-5s\t%-s\t%-20s\t%-30s\n", "姓名", "性别", "年龄", "号码", "住址");  //写入标头信息inti=0;
for (i=0; i<pc->sz; i++)
    {
fprintf(fp, "%-10s\t%-5s\t%-d\t%-15s\t%-30s\n", pc->data[i].name, pc->data[i].sex,
pc->data[i].age, pc->data[i].number, pc->data[i].address);
    }
//关闭文件fclose(fp);
fp=NULL;
}


🌱test.c         主函数源文件

#define _CRT_SECURE_NO_WARNINGS 1   #include"Contact.h"//第三代通讯录(文件版),刷新git提交voidmenuByCon()
{
printf("***************************************\n");
printf("**********  0.退出  1.显示  **********\n");
printf("**********  2.增加  3.删除  **********\n");
printf("**********  4.查找  5.修改  **********\n");
printf("**********  6.排序  7.数量  **********\n");
printf("***************************************\n");
}
enumMenuByCon{
退出, 显示, 增加, 删除,
查询, 修改, 排序, 数量};
intmain()
{
Conc1;//创建了一个通讯录ConInit(&c1);
intinput=1;
while (input)
    {
menuByCon();
printf("请选择你的操作(只能输入数字):>");
scanf("%d", &input);
system("cls");
switch (input)
        {
case退出:
printf("退出通讯录系统!\n");
ConSave(&c1);//保存通讯录ConDestroy(&c1);//销毁通讯录break;
case显示:
ConDisplay(&c1);
break;
case增加:
ConAdd(&c1);
break;
case删除:
ConDelte(&c1);
break;
case查询:
ConFind(&c1);
break;
case修改:
ConRevise(&c1);
break;
case排序:
ConSort(&c1);
break;
case数量:
printf("当前通讯录中信息数为:%d\n", ConInfoNum(&c1));
break;
default:
printf("选择错误,请重新选择!\n");
break;
        }
    }
return0;
}

🌳总结

 以上就是三个不同版本通讯录的分享,如果是学习的话,可以从静态版开始,逐步升级为文件版,后期可以尝试升级为数据库版;如果是为了课设做准备的话,可以直接看文件版,功能全面,运行稳定。总之,以上就是本期C语言课设分享的全部内容了,作为代码分享类文章,并没有进行太过详细的讲解,但代码量是可以得到保证的。

792be0acc5e64a1bb75b745878fe797a.jpg


 如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正



目录
相关文章
|
15天前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
27 1
|
1月前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
1月前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
22 2
|
1月前
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
|
1月前
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
|
1月前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
1月前
|
C语言
【C语言】探索文件读写函数的全貌(一)
【C语言】探索文件读写函数的全貌
|
5月前
|
C语言
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
44 0
|
存储 缓存 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)