通讯录-C/C++

问题描述

设计一个通讯录管理程序,要求程序采用模块化设计方法,程序应采用由主控程序调用各模块实现各个功能的方式。程序应具有如下功能:输入记录显示记录查找记录插入记录记录排序删除记录等。数据存储采用外存存储形式,存放于外存的数据应进行加密处理。

设计分析

通讯录中的数据可以看作是由多条记录组成的一个二维表格,一行对应一条记录,每条记录都有同样的字段序列。在管理程序中对数据进行组织时,可以使用结构体(struct)来描述记录,结构体中的成员即就是记录中的各个字段。通过结构体数组即可以存放通讯录中的多条记录。数据在外存进行存取操作时,可以使用按记录存取的方式进行。

例如,可以采用如下形式定义通讯录对应的结构体:

struct record {// 记录char name[20];char phone[12];char adress[50];char postcode[8];char e_mail[20];
}student[SIZE];

解决方案

通过定义以下各函数实现程序功能模块的功能,在主函数中调用各函数:

(1)通讯录管理菜单

int menu_select() {// 菜单选择char s[80];int a;system("cls");// 清屏printf("\t\t***********欢迎进入通讯管理界面********\n\n");printf("\t\t\t0. 输入记录\n");printf("\t\t\t1. 显示记录\n");printf("\t\t\t2. 按姓名查找\n");printf("\t\t\t3. 按电话号码查找\n");printf("\t\t\t4. 插入记录 \n");printf("\t\t\t5. 按姓名排序\n");printf("\t\t\t6. 删除记录\n");printf("\t\t\t7. Quit\n");printf("\t\t***********************************************\n\n");do {printf("Enter you choice(0~7):");scanf("%s", s);a = atoi(s);// 将字符串转化成整型值} while (a < 0 || a>7);// 当输入小于0或大于7,将循环输入return a;
}

(2)输入记录

int adduser() {// 添加记录printf("\t\t\t**************** 请输入用户信息 ****************\n");printf("\t\t\t输入姓名:\n");scanf("%s", student[num].name);printf("\t\t\t输入电话号码:\n");scanf("%s", student[num].phone);printf("\t\t\t输入地址:\n");scanf("%s", student[num].adress);printf("\t\t\t输入邮编:\n");scanf("%s", student[num].postcode);printf("\t\t\t输入e-mail:\n");scanf("%s", student[num].e_mail);num++;printf("\t\t\t是否继续添加?(Y/N):\n");if (getch() == 'y' || getch() == 'Y')// 输入大写和小写字母y都行adduser();// 再次调用添加记录return(0);
}

(3)显示记录

void list() {// 显示记录int i;system("cls");// 清屏if (num != 0) {// 如果记录的数字不为0,逐个打印记录printf("\t\t\t*************** 以下为通讯录所有信息************\n");for (i = 0; i < num; i++) {printf("\t\t\t姓名:%s\n", student[i].name);printf("\t\t\t电话:%s\n", student[i].phone);printf("\t\t\t地址:%s\n", student[i].adress);printf("\t\t\t邮编:%s\n", student[i].postcode);printf("\t\t\te-mail:%s\n", student[i].e_mail);if (i + 1 < num) {system("pause");// 程序暂停}}printf("\t\t\t************************************************\n");}else// 如果记录数字为0,则程序中无记录printf("\t\t\t通讯录中无任何纪录\n");printf("\t\t\t按任意键返回主菜单:\n");getch();// 获取按下的任意键return;
}

(4)按姓名查找记录

int searchbyname() {// 按姓名查找int mark = 0;// 定义一个变量作为标记int i;// 定义一个循环辅助变量printf("\t\t\t***************** 按姓名查找 *******************\n");char name[20];printf("\t\t\t请输入姓名:\n");scanf("%s", name);for (i = 0; i < num; i++) {if (strcmp(student[i].name, name) == 0) {// 将输入的姓名与存入的比较,相同为0进行打印printf("\t\t\t************* 以下是您查找的用户信息 ***********\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t************************************************\n");mark++;// 标记加1if ((i + 1) < num) {// 如果遍历到某一位置加1还是比所有记录的数小,选择继续查找或终止查找printf("\t\t\t是否继续查找相同名字的用户信息:(y/n)\n");if (getch() == 'y' || getch() == 'Y') {// 输入y则继续查找continue;}elsereturn(0);}else {printf("\t\t\t按任意键返回主菜单");getch();// 获取按下的任意键return(0);}}}if (mark == 0) {// 如果mark的值为0,表示没有此名字的用户记录printf("\t\t\t没有相同姓名的用户纪录\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return(0);}return 0;
}

(5)按电话号码查找记录

int searchbyphone() {// 按电话号码查找int mark = 0;// 定义一个变量用于标记int i;// 定义一个循环辅助变量printf("\t\t\t****************** 按电话查找 ******************\n");char phone[10];printf("\t\t\t请输入电话号码:\n");scanf("%s", phone);for (i = 0; i < num; i++) {if (strcmp(student[i].phone, phone) == 0) {// 将输入的电话号码与存入的比较,相同为0进行打印 printf("\t\t\t************** 以下是您查找的用户信息 **********\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t************************************************\n");printf("\t\t\t按任意键返回主菜单\n");mark++;// 标记加1getch();// 获取按下的任意键return(0);}}if (mark == 0) {// 如果mark的值为0,表示没有此电话号码的记录printf("\t\t\t没有改用户的信息\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return(0);}return(0);
}

(6)按电话号码删除记录

void deletebyphone() {// 按电话号码删除记录int i, j;// 定义循环辅助变量int deletemark = 0;// 定义变量用于标记char phone[20];printf("\t\t\t请输入要删除用户电话号码:\n");scanf("%s", phone);if (num == 0) {// 记录变量为0,则无输入记录printf("\t\t\t对不起,文件中无任何纪录\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return;}for (i = 0; i < num; i++) {if (strcmp(student[i].phone, phone) == 0) {// 比较输入的电话号码与存入的电话号码比较,相同为0printf("\t\t\t以下是您要删除的用户纪录:\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t是否删除?(y/n)");if (getch() == 'y' || getch() == 'Y') {// 判断是否确认删除for (j = i; j < num - 1; j++)// 循环将后一条记录前移1个student[j] = student[j + 1];num--;deletemark++;// 删除标记加1printf("\t\t\t删除成功");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyphone();// 调用按电话号码删除记录return;}elsereturn;}continue;}if (deletemark == 0) {// 判断是否有此电话号码的用户信息printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyphone();// 调用按电话号码删除记录return;}return;
}

(7)按姓名删除记录

void deletebyname() {// 按姓名删除记录int a = 0;// 循环辅助变量int findmark = 0;// 查找标记int j;// 循环辅助变量int deletemark = 0;// 删除标记int i;// 循环辅助变量char name[20];printf("\t\t\t请输入要删除用户姓名:\n");scanf("%s", name);for (i = a; i < num; i++) {if (strcmp(student[i].name, name) == 0) {// 比较输入的姓名与存入的姓名比较,相同为0printf("\t\t\t以下是您要删除的用户纪录:");findmark++;// 查找标记加1printf("\t\t\t________________________________");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t________________________________");printf("\t\t\t是否删除?(y/n)");if (getch() == 'y' || getch() == 'Y') {for (j = i; j < num - 1; j++)// 遍历记录个数-1,将后一个数据逐个替代前一个数据student[j] = student[j + 1];num--;// 总记录数减1deletemark++;// 删除标记加1printf("\t\t\t删除成功");if ((i + 1) < num) {printf("\t\t\t是否继续删除相同姓名的用户信息?(y/n)");if (getch() == 'y') {a = i;// 将当前i值赋给a用于后续继续删除相同姓名的用户信息continue;}}printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}if ((i + 1) < num) {// 判断是否将所有用户信息遍历完printf("\t\t\t是否继续删除相同姓名的用户信息?(y/n)");if (getch() == 'y' || getch() == 'Y') {// 判断是否继续删除相同姓名的用户信息a = i;// 将当前i值赋给a用于后续继续删除相同姓名的用户信息continue;}}}elsecontinue;}if ((deletemark == 0) && (findmark == 0)) {// 判断删除标记和查找标记是否同时为0,为0则没有该用户信息printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}else if (findmark != 0) {// 判断查找标记不为0,则没有重名printf("\t\t\t没有重名信息");printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}
}

(8)删除记录

int dele() {// 删除记录char choic;printf("\t\t\t1-按电话号码删除 2-按姓名删除");printf("\t\t\t请选择:");choic = getch();// 从键盘获取字符switch (choic) {case '1':deletebyphone(); break;// 按电话号码删除case '2':deletebyname(); break;// 按姓名删除}return(0);
}

(9)按姓名排序

int sortbyname() {// 按姓名排序int i, j;// 循环辅助变量struct record tmp;for (i = 1; i < num; i++) {if (strcmp(student[i].name, student[i - 1].name) < 0) {// 比较相邻两个姓名小于0时,则i位置的姓名要排在前面tmp = student[i];j = i - 1;do {student[j + 1] = student[j];j--;} while ((strcmp(tmp.name, student[j].name) < 0 && j >= 0));student[j + 1] = tmp;}}printf("\t\t\t排序成功,是否显示?(y/n)");if (getch() == 'y')// 是否显示list();// 调用显示记录return(0);
}

(10)读取外存文件数据

void readfile() {/*从文件student_address_book.dat首部开始,按记录长度sizeof(struct record)*//*循环读出每条记录,直至文件尾部;每读出一条记录,则调用encrypt()函数*//*对相应字段进行解密处理,并使记录计数器num加1,统计出记录总数。 */FILE* ptr = fopen("student_address_book.dat", "r");//打开文件if (ptr == NULL) {//判断文件是否成功打开printf("open file student_address_book.dat打开失败");return;}num = 0;while (fread(&student[num], sizeof(struct record), 1, ptr) == 1) {//循环读取每条记录并进行解密encrypt(student[num].name);encrypt(student[num].phone);encrypt(student[num].adress);encrypt(student[num].postcode);encrypt(student[num].e_mail);num++;}fclose(ptr);//关闭文件ptr = NULL;//将文件设置为空
}

(11)向外存文件写入数据

void writefile() {/*根据记录总数num,从首条记录即结构体数组首元素student[0]开始, *//*调用encrypt()函数对相应字段进行加密处理,并将当前记录整体写入*//*文件student_address_book.dat中,直至最后一条记录。 *//*也可以先对所有记录进行加密处理,然后整体一次性写入文件。 */FILE* ptw = fopen("student_address_book.dat", "w");//打开文件if (ptw == NULL) {//判断文件是否成功打开printf("open file student_address_book.dat打开失败");return;}int i = 0;//循环辅助变量for (i = 0; i < num; i++) {//把联系人信息循环写入文件中并进行加密处理encrypt(student[i].name);encrypt(student[i].phone);encrypt(student[i].adress);encrypt(student[i].postcode);encrypt(student[i].e_mail);fwrite(&student[i], sizeof(struct record), 1, ptw);//将数据整体写入文件}fclose(ptw);//关闭文件ptw = NULL;//将文件设置为空
}

(12)用户信息加密处理

void encrypt(char* pwd) {//对数据进行加密操作/*与15(二进制码是00001111)异或,实现低四位取反,高四位保持不变*/while (*pwd != '\0') {//循环遍历数组*pwd = *pwd ^ 15;//将每条数据与15进行异或 pwd++;}
}

(13)主函数

int main() {printf("\t\t************************************************\n");printf("\t\t***************欢迎进入通讯录*******************\n");printf("\t\t*************************************************\n");printf("按任意键进入主菜单\n");readfile();//读取文件里的内容getch();int selectnum;while (1) {selectnum = menu_select();switch (selectnum) {case 0:{adduser();// 调用添加记录break;}case 1:{list();// 调用显示记录break;}case 2:{searchbyname();// 调用按姓名查找break;}case 3:{searchbyphone();// 调用按电话号码查找break;}case 4:{adduser();// 调用添加记录break;}case 5:{sortbyname();// 调用按姓名排序break;}case 6:{dele();// 调用删除记录break;}case 7:{printf("BYE BYE!\n");system("pause");// 程序暂停writefile();//将程序中的数据写入文件getchar();// 从缓冲区读取一个字符exit(0);// 退出程序}}}getchar();// 从缓冲区读取一个字符return 0;
}

最终整合代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>#define SIZE 100struct record {// 记录char name[20];char phone[12];char adress[50];char postcode[8];char e_mail[20];
}student[SIZE];int num;int menu_select() {// 菜单选择char s[80];int a;system("cls");// 清屏printf("\t\t***********欢迎进入通讯管理界面********\n\n");printf("\t\t\t0. 输入记录\n");printf("\t\t\t1. 显示记录\n");printf("\t\t\t2. 按姓名查找\n");printf("\t\t\t3. 按电话号码查找\n");printf("\t\t\t4. 插入记录 \n");printf("\t\t\t5. 按姓名排序\n");printf("\t\t\t6. 删除记录\n");printf("\t\t\t7. Quit\n");printf("\t\t***********************************************\n\n");do {printf("Enter you choice(0~7):");scanf("%s", s);a = atoi(s);// 将字符串转化成整型值} while (a < 0 || a>7);// 当输入小于0或大于7,将循环输入return a;
}int adduser() {// 添加记录printf("\t\t\t**************** 请输入用户信息 ****************\n");printf("\t\t\t输入姓名:\n");scanf("%s", student[num].name);printf("\t\t\t输入电话号码:\n");scanf("%s", student[num].phone);printf("\t\t\t输入地址:\n");scanf("%s", student[num].adress);printf("\t\t\t输入邮编:\n");scanf("%s", student[num].postcode);printf("\t\t\t输入e-mail:\n");scanf("%s", student[num].e_mail);num++;printf("\t\t\t是否继续添加?(Y/N):\n");if (getch() == 'y' || getch() == 'Y')// 输入大写和小写字母y都行adduser();// 再次调用添加记录return(0);
}void list() {// 显示记录int i;system("cls");// 清屏if (num != 0) {// 如果记录的数字不为0,逐个打印记录printf("\t\t\t*************** 以下为通讯录所有信息************\n");for (i = 0; i < num; i++) {printf("\t\t\t姓名:%s\n", student[i].name);printf("\t\t\t电话:%s\n", student[i].phone);printf("\t\t\t地址:%s\n", student[i].adress);printf("\t\t\t邮编:%s\n", student[i].postcode);printf("\t\t\te-mail:%s\n", student[i].e_mail);if (i + 1 < num) {system("pause");// 程序暂停}}printf("\t\t\t************************************************\n");}else// 如果记录数字为0,则程序中无记录printf("\t\t\t通讯录中无任何纪录\n");printf("\t\t\t按任意键返回主菜单:\n");getch();// 获取按下的任意键return;
}int searchbyname() {// 按姓名查找int mark = 0;// 定义一个变量作为标记int i;// 定义一个循环辅助变量printf("\t\t\t***************** 按姓名查找 *******************\n");char name[20];printf("\t\t\t请输入姓名:\n");scanf("%s", name);for (i = 0; i < num; i++) {if (strcmp(student[i].name, name) == 0) {// 将输入的姓名与存入的比较,相同为0进行打印printf("\t\t\t************* 以下是您查找的用户信息 ***********\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t************************************************\n");mark++;// 标记加1if ((i + 1) < num) {// 如果遍历到某一位置加1还是比所有记录的数小,选择继续查找或终止查找printf("\t\t\t是否继续查找相同名字的用户信息:(y/n)\n");if (getch() == 'y' || getch() == 'Y') {// 输入y则继续查找continue;}elsereturn(0);}else {printf("\t\t\t按任意键返回主菜单");getch();// 获取按下的任意键return(0);}}}if (mark == 0) {// 如果mark的值为0,表示没有此名字的用户记录printf("\t\t\t没有相同姓名的用户纪录\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return(0);}return 0;
}int searchbyphone() {// 按电话号码查找int mark = 0;// 定义一个变量用于标记int i;// 定义一个循环辅助变量printf("\t\t\t****************** 按电话查找 ******************\n");char phone[10];printf("\t\t\t请输入电话号码:\n");scanf("%s", phone);for (i = 0; i < num; i++) {if (strcmp(student[i].phone, phone) == 0) {// 将输入的电话号码与存入的比较,相同为0进行打印 printf("\t\t\t************** 以下是您查找的用户信息 **********\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t************************************************\n");printf("\t\t\t按任意键返回主菜单\n");mark++;// 标记加1getch();// 获取按下的任意键return(0);}}if (mark == 0) {// 如果mark的值为0,表示没有此电话号码的记录printf("\t\t\t没有改用户的信息\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return(0);}return(0);
}void deletebyphone() {// 按电话号码删除记录int i, j;// 定义循环辅助变量int deletemark = 0;// 定义变量用于标记char phone[20];printf("\t\t\t请输入要删除用户电话号码:\n");scanf("%s", phone);if (num == 0) {// 记录变量为0,则无输入记录printf("\t\t\t对不起,文件中无任何纪录\n");printf("\t\t\t按任意键返回主菜单\n");getch();// 获取按下的任意键return;}for (i = 0; i < num; i++) {if (strcmp(student[i].phone, phone) == 0) {// 比较输入的电话号码与存入的电话号码比较,相同为0printf("\t\t\t以下是您要删除的用户纪录:\n");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t是否删除?(y/n)");if (getch() == 'y' || getch() == 'Y') {// 判断是否确认删除for (j = i; j < num - 1; j++)// 循环将后一条记录前移1个student[j] = student[j + 1];num--;deletemark++;// 删除标记加1printf("\t\t\t删除成功");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyphone();// 调用按电话号码删除记录return;}elsereturn;}continue;}if (deletemark == 0) {// 判断是否有此电话号码的用户信息printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyphone();// 调用按电话号码删除记录return;}return;
}void deletebyname() {// 按姓名删除记录int a = 0;// 循环辅助变量int findmark = 0;// 查找标记int j;// 循环辅助变量int deletemark = 0;// 删除标记int i;// 循环辅助变量char name[20];printf("\t\t\t请输入要删除用户姓名:\n");scanf("%s", name);for (i = a; i < num; i++) {if (strcmp(student[i].name, name) == 0) {// 比较输入的姓名与存入的姓名比较,相同为0printf("\t\t\t以下是您要删除的用户纪录:");findmark++;// 查找标记加1printf("\t\t\t________________________________");printf("\t\t\t姓名: %s", student[i].name);printf("\t\t\t电话: %s", student[i].phone);printf("\t\t\t地址: %s", student[i].adress);printf("\t\t\te-mail:%s", student[i].e_mail);printf("\t\t\t________________________________");printf("\t\t\t是否删除?(y/n)");if (getch() == 'y' || getch() == 'Y') {for (j = i; j < num - 1; j++)// 遍历记录个数-1,将后一个数据逐个替代前一个数据student[j] = student[j + 1];num--;// 总记录数减1deletemark++;// 删除标记加1printf("\t\t\t删除成功");if ((i + 1) < num) {printf("\t\t\t是否继续删除相同姓名的用户信息?(y/n)");if (getch() == 'y') {a = i;// 将当前i值赋给a用于后续继续删除相同姓名的用户信息continue;}}printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}if ((i + 1) < num) {// 判断是否将所有用户信息遍历完printf("\t\t\t是否继续删除相同姓名的用户信息?(y/n)");if (getch() == 'y' || getch() == 'Y') {// 判断是否继续删除相同姓名的用户信息a = i;// 将当前i值赋给a用于后续继续删除相同姓名的用户信息continue;}}}elsecontinue;}if ((deletemark == 0) && (findmark == 0)) {// 判断删除标记和查找标记是否同时为0,为0则没有该用户信息printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}else if (findmark != 0) {// 判断查找标记不为0,则没有重名printf("\t\t\t没有重名信息");printf("\t\t\t没有该用户的纪录");printf("\t\t\t是否继续删除?(y/n)");if (getch() == 'y' || getch() == 'Y')// 判断是否继续删除deletebyname();// 调用按姓名删除记录return;}
}int dele() {// 删除记录char choic;printf("\t\t\t1-按电话号码删除 2-按姓名删除");printf("\t\t\t请选择:");choic = getch();// 从键盘获取字符switch (choic) {case '1':deletebyphone(); break;// 按电话号码删除case '2':deletebyname(); break;// 按姓名删除}return(0);
}int sortbyname() {// 按姓名排序int i, j;// 循环辅助变量struct record tmp;for (i = 1; i < num; i++) {if (strcmp(student[i].name, student[i - 1].name) < 0) {// 比较相邻两个姓名小于0时,则i位置的姓名要排在前面tmp = student[i];j = i - 1;do {student[j + 1] = student[j];j--;} while ((strcmp(tmp.name, student[j].name) < 0 && j >= 0));student[j + 1] = tmp;}}printf("\t\t\t排序成功,是否显示?(y/n)");if (getch() == 'y')// 是否显示list();// 调用显示记录return(0);
}void encrypt(char* pwd) {//对数据进行加密操作/*与15(二进制码是00001111)异或,实现低四位取反,高四位保持不变*/while (*pwd != '\0') {//循环遍历数组*pwd = *pwd ^ 15;//将每条数据与15进行异或 pwd++;}
}void readfile() {/*从文件student_address_book.dat首部开始,按记录长度sizeof(struct record)*//*循环读出每条记录,直至文件尾部;每读出一条记录,则调用encrypt()函数*//*对相应字段进行解密处理,并使记录计数器num加1,统计出记录总数。 */FILE* ptr = fopen("student_address_book.dat", "r");//打开文件if (ptr == NULL) {//判断文件是否成功打开printf("open file student_address_book.dat打开失败");return;}num = 0;while (fread(&student[num], sizeof(struct record), 1, ptr) == 1) {//循环读取每条记录并进行解密encrypt(student[num].name);encrypt(student[num].phone);encrypt(student[num].adress);encrypt(student[num].postcode);encrypt(student[num].e_mail);num++;}fclose(ptr);//关闭文件ptr = NULL;//将文件设置为空
}void writefile() {/*根据记录总数num,从首条记录即结构体数组首元素student[0]开始, *//*调用encrypt()函数对相应字段进行加密处理,并将当前记录整体写入*//*文件student_address_book.dat中,直至最后一条记录。 *//*也可以先对所有记录进行加密处理,然后整体一次性写入文件。 */FILE* ptw = fopen("student_address_book.dat", "w");//打开文件if (ptw == NULL) {//判断文件是否成功打开printf("open file student_address_book.dat打开失败");return;}int i = 0;//循环辅助变量for (i = 0; i < num; i++) {//把联系人信息循环写入文件中并进行加密处理encrypt(student[i].name);encrypt(student[i].phone);encrypt(student[i].adress);encrypt(student[i].postcode);encrypt(student[i].e_mail);fwrite(&student[i], sizeof(struct record), 1, ptw);//将数据整体写入文件}fclose(ptw);//关闭文件ptw = NULL;//将文件设置为空
}int main() {printf("\t\t************************************************\n");printf("\t\t***************欢迎进入通讯录*******************\n");printf("\t\t*************************************************\n");printf("按任意键进入主菜单\n");readfile();//读取文件里的内容getch();int selectnum;while (1) {selectnum = menu_select();switch (selectnum) {case 0:{adduser();// 调用添加记录break;}case 1:{list();// 调用显示记录break;}case 2:{searchbyname();// 调用按姓名查找break;}case 3:{searchbyphone();// 调用按电话号码查找break;}case 4:{adduser();// 调用添加记录break;}case 5:{sortbyname();// 调用按姓名排序break;}case 6:{dele();// 调用删除记录break;}case 7:{printf("BYE BYE!\n");system("pause");// 程序暂停writefile();//将程序中的数据写入文件getchar();// 从缓冲区读取一个字符exit(0);// 退出程序}}}getchar();// 从缓冲区读取一个字符return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45227.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++——类和对象(上)

文章目录 一、类的定义1.类定义格式2.访问限定符3.类域 二、实例化1.实例化概念2.对象⼤⼩ 三、 this指针 一、类的定义 1.类定义格式 与定义结构体类似 class ST {//成员变量int val;//成员函数void print(){cout << val << endl;}};class为定义类的关键字&…

SQL笔试题【数据岗】

视频号数据分析组外包招聘笔试题时间限时 45 分钟完成 题目 根据 3 张表表结构&#xff0c;写出具体求解的 SQL 代码 &#xff08;搞笑品类定义&#xff1a;视频分类或者视频创建者分类为“搞笑”&#xff09; l 题目 1&#xff1a;输出一张搞笑品类 dws 表&#xff0c;用于分…

从 QWebEnginePage 打印文档

QWebEnginePage 是 Qt WebEngine 模块中的一个类&#xff0c;它提供了用于处理网页内容的接口。如果你想要打印 QWebEnginePage 中的内容&#xff0c;你可以使用 QPrinter 和 QPrintDialog 类来实现。 项目配置了 Qt WebEngine 模块&#xff0c;并且在你的.pro文件中包含了相应…

el-date-picker 禁用 之前 和 之后 的时间

<el-date-pickerv-model"ruleForm.startTime"type"date"placeholder"请选择"format"YYYY-MM-DD"value-format"YYYY-MM-DD":disabled-date"pickerOptions"clearable/>const pickerOptions (time) > { if…

解析 pdfminer pdfparser.py

解析 pdfminer pdfparser.py 1. 导入必要的模块2. 定义PDFParser类2.1 初始化方法2.2 设置文档方法2.3 处理关键词方法举例说明: 3. 定义PDFStreamParser类3.1 初始化方法3.2 刷新方法3.3 处理关键词方法 总结 今天我们来看一段Python代码,这段代码实现了一个PDF文件的解析器。…

Python项目开发实战,掷硬币的连胜,案例教程编程实例课程详解

在Python中进行实战项目,比如模拟掷硬币并记录连胜次数,是一个既有趣又能加深理解随机数生成、循环控制、条件判断等编程基础的好方法。下面,我将逐步引导你完成一个详细的Python项目,该项目将模拟掷硬币的过程,并追踪记录连胜的次数,同时我们会深入探讨一些编程概念,如…

查看尝试登服务器ssh 访问ip地址

不指定时间查看尝试登录服务器的SSH访问IP地址 # CentOS/RHEL系统 zgrep "sshd" /var/log/secure-* | grep "Failed password" | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -n 10检查过去7天的日志尝试登录服务器的SSH访问IP地址 # CentOS…

AutoMQ vs Kafka: 来自小红书的独立深度评测与对比

测试背景 当前小红书消息引擎团队与 AutoMQ 团队正在深度合作&#xff0c;共同推动社区建设&#xff0c;探索云原生消息引擎的前沿技术。本文基于 OpenMessaging 框架&#xff0c;对 AutoMQ 进行了全面测评。欢迎大家参与社区并分享测评体验。 01 测试结论 本文主要测评云…

AI克隆声音,基于函数计算部署GPT-Sovits语音生成模型

阿里云的 https://developer.aliyun.com/adc/scenario/808348a321844a62b922187d89cd5077 还是 函数计算 FC (aliyun.com) 选择 语音克隆生成 GPT-SOVITS 通过访问域名就能访问 就可以上传个人的声音&#xff0c;然后进行输出 。

【逆向基础】十、逆向工具分享之DIE(Detect It Easy)

一、简介 DIE&#xff08;Detect It Easy&#xff09;是一款可以轻松检测PE文件的程序&#xff1b;其主要作用是查壳&#xff0c;并将pe文件的内容解析出来&#xff0c;包括PE文件中包含的导入函数、导出函数的名称及地址&#xff0c;入口函数地址等&#xff0c;是技术人员分析…

C# —— 数组的告诫查询方法

查询数组元素的方法 1.通过索引值找元素 a[0] 2.通过循环进行遍历 查询数组的每一个元素 int[] a1 new int[] { 1, 2, 3 }; Console.WriteLine(a1[0]);// 通过循环进行遍历 查询数组的每一个元素 for (int i 0; i < a1.Length; i) {// Console.WriteLine(a1[i]); } 3 in…

nuPlan 是一个针对自动驾驶车辆的闭环机器学习(ML-based)规划基准测试

nuPlan: A closed-loop ML-based planning benchmark for autonomous vehicles nuPlan 是一个针对自动驾驶车辆的闭环机器学习&#xff08;ML-based&#xff09;规划基准测试 Abstract In this work, we propose the world’s first closed-loop ML-based planning benchmar…

乐观锁原理

乐观锁是一种并发控制的方法&#xff0c;主要用于多线程环境下&#xff0c;用于保证数据的一致性。其核心思想是&#xff1a;"在多个事务中乐观地读取数据&#xff0c;在提交时再验证是否有冲突&#xff0c;如果没有&#xff0c;则提交&#xff1b;如果有&#xff0c;则回…

Excel第30享:基于辅助列的条件求和

1、需求描述 如下图所示&#xff0c;现要统计2022年YTD&#xff08;Year To Date&#xff1a;年初至今日&#xff09;各个人员的“上班工时&#xff08;a2&#xff09;”。 下图为系统直接导出的工时数据明细样例。 2、解决思路 Step1&#xff1a;确定逻辑。“从日期中提取出…

sqlmap确定目标/实操

安装kali&#xff0c;kali自带sqlmap&#xff0c;在window系统中跟linux系统操作有区别 sqlmap是一款自动化SQL工具&#xff0c;打开kali终端&#xff0c;输入sqlmap&#xff0c;出现以下界面&#xff0c;就说明sqlmap可用。 sqlmap确定目标 一、sqlmap直连数据库 1、直连数据库…

26.Labview波形图、XY图、强度图使用精讲

我们如何使用Labview显示曲线或者制作出下面这种我们想要的曲线并随着我们输入值的变化而变化呢&#xff1f; 本文详细讲解一下每种波形图的使用方式&#xff0c;帮助大家深入了解波形图的使用技巧。 文章中所有程序均可在百度网盘下载&#xff0c;下载方式&#xff1a;复制下…

GPT生成文本的实际案例 - Transformer教程

大家好&#xff0c;今天我们要聊一聊一个非常有趣的话题——GPT生成文本的实际案例&#xff0c;并且通过这篇文章来了解一下Transformer教程。这些技术在自然语言处理&#xff08;NLP&#xff09;领域掀起了巨大的波澜&#xff0c;不仅改变了我们与计算机交互的方式&#xff0c…

单件s_instance作为类成员静态变量与函数静态局部变量的区别

在C中&#xff0c;静态成员变量和静态局部变量虽然都是静态的&#xff0c;但它们的作用和使用方式有明显的区别&#xff1a; 1. **静态成员变量**&#xff1a; - 静态成员变量是类的一部分&#xff0c;它是类的所有实例对象共享的&#xff0c;只有一份拷贝。通常在类的声明…

虚拟机 VMware Workstation- 安装详细步骤

目录 虚拟化概念VMware Workstation 简介一、安装准备1. 安装环境2. 软件下载 二、常见问题1. 虚拟机的【默认位置】会在C盘&#xff0c;盘符内存不够的建议改为D盘或别的盘符2. 验证许可证是否密钥是否成功。进入虚拟机点击【帮助】下的关于VMware Workstation(A)可以查看验证…

YOLOv10改进 | 主干/Backbone篇 | 利用RT-DETR特征提取网络PPHGNetV2改进YOLOv10

一、本文介绍 本文给大家带来利用RT-DETR模型主干HGNet去替换YOLOv10的主干&#xff0c;RT-DETR是今年由百度推出的第一款实时的ViT模型&#xff0c;其在实时检测的领域上号称是打败了YOLO系列&#xff0c;其利用两个主干一个是HGNet一个是ResNet&#xff0c;其中HGNet就是我们…