📄 电话目录系统(二进制形式).cpp
字号:
#include <stdio.h>
#include <windows.h>
#include <string.h>
void ptdet(struct subscriber *sub);//接收用户的详细资料
void addsubs(); //增加记录
void viewdir(); //查看记录
/* 定义结构体用于存储订户的详细资料 */
struct subscriber //结构类型名:用户
{
char name[30]; //用于存放用户姓名
char address[50]; //用于存放用户住址
long int telno; //用于存放用户电话号码
};
void main()
{
int choice=0; //用于存放主菜单的选项,初始化为0
/*下面是:陈列主菜单,用于接受用户的选项 */
while(choice!=7)
{
printf("\t电话目录系统\n");
printf("1. 增加新的用户详细资料\n");
printf("2. 查看目录\n");
printf("3. 离开\n");
printf("\n请选择上面的选项: ");
lab1:scanf("%d", &choice);
/*下面是:基于菜单中的选项,调用适当的函数 */
if(choice==1) //当你选择的是1时
addsubs(); //就调用addsubs()函数;
else if(choice==2) //否则,当你选择的是6时
viewdir(); //就调用viewdir()函数;
else if(choice==3) //否则,当你选择的是7时
exit(0); //就调用exit()函数,结束程序;
else //否则,当你选择的不是以上的7项时
{
system("cls"); //都调用系统的清屏指令
printf("\t电话目录系统\n");
printf("1. 增加新的用户详细资料\n");
printf("2. 查看目录\n");
printf("3. 离开\n");
printf("\n菜单中没有你要的选项,请重新输入:");
goto lab1;
}
}
}
/*下面函数的功能是:增加用户的详细资料*/
void addsubs()
{
FILE *fp; //申明一文件指针,即文件流
int newfile=0; //定义newfile变量,用于标记文件创建是否成功
int i=0; //用作循环记数器
int j; //用作循环记数器
int readctr=0; //用于标记读出的记录项
struct subscriber sub_arr[100]; //用于存放从文件输出缓冲区中读出的记录
struct subscriber new_sub; //用于存放从键盘输入的记录
struct subscriber temp_sub; //交换记录位置时,用作空位
char flag='n'; //用于标记读取的姓名的ASCII值与输入的姓名的ASCII值谁大
int size_s=sizeof(struct subscriber); //计算出存储一个结构所需的字节大小
fp=fopen("telefon.txt", "r+b"); //首先,以可读可写的模式打开一文本文件:telefon.dtxt
if(fp==NULL) //如果fp为空,即表示打开telefon.txt不成功
{
fp=fopen("telefon.txt", "wb"); //就另以只写的模式创建一文本文件:telefon.txt
if(fp==NULL) //如果fp为空,即表示telefon.txt创建不成功
{
printf("\t磁盘空间不足,文件创建不成功\n\n");
}
else //如果telefon.txt创建成功
newfile=1; //就让newfile标记器存放1,表示telefon.txt文件创建成功
}
/*不管是以可读模式打开成功,还是以可写模式打开成功,还是以可读可写模式打开都成功*/
system("cls"); //都先调用系统的清屏指令,把屏幕清干净
printf("\t请输入新的用户详细资料:");
ptdet(&new_sub); //调用接受新用户详细资料的函数
if(newfile==1) //如果newfile标记器存放1,表示telefon.txt是一新的文件,可增加记录
{
fwrite(&new_sub, size_s, 1, fp); //接着将新输入的记录写入到telefon.txt文件中
}
else //如果newfile标记器存放非1,表示telefon.dat是已有的文件,也可增加记录到结构体的数组中
{
i=0; //首先使结构体的数组的下标数i为0,表示第一个元素
readctr=fread(&sub_arr[i], size_s, 1, fp); //接着先读取第一条记录到结构体数组中,读取成功的话,readctr将获得整型值1
/*然后,再继续读取文件中的每条记录,直到最末尾的一条*/
while(readctr==1) //只要readctr的值为1,表示前一记录读取成功,也可继读下一条
{
/*如果刚输入的姓名的ASCII值小于等于数组中每条记录中姓名的ASCII值,且flag为'n'*/
if((strcmp(sub_arr[i].name,new_sub.name))>=0 && flag=='n') //如果是
{
/*就将新输入的记录插到数组中刚读出来的这条记录之前*/
temp_sub=sub_arr[i]; //将读出来的从sub_arr[i]拿开
sub_arr[i]=new_sub; //再将新输入的放入到sub_arr[i]
i++; //下标值加1
sub_arr[i]=temp_sub; //再将原读出来的放到sub_arr的下一个位
flag='y'; //将flag上的值改为'y',表示插入成功
}
/*如果刚输入的姓名的ASCII值大于数组中每条记录中姓名的ASCII值,或者是数组中还没有任何一条记录时*/
i++; //就使数组下标加1
readctr=fread(&sub_arr[i], size_s, 1, fp); //并且,继续从telefon.txt文件中读取下一记录到sub_arr[i]数组中
}
if(flag=='n') //如果flag上始终是'n',表示读取的记录的姓名的ASCII值始终没有一个比输入的姓名的ASCII值大
{
sub_arr[i]=new_sub; //就将新记录放于最后
i++; //并且让下标值加1,以备下面for循环用
}
rewind(fp); //重置文件活动指针于文件开头处
for(j=0; j<i; j++) //循环将sub_arr数组中每条记录写到telefon.txt文件中
{
fwrite(&sub_arr[j], size_s, 1, fp); //将sub_arr数组中第j+1个元素上的记录写到telefon.txt文件的输出缓冲区
}
}
system("cls"); //都调用系统的清屏指令
printf("用户详细资料添加成功\n\n");
fclose(fp); //关闭文件
}
/*下面函数的功能是:接收用户的详细资料*/
void ptdet(struct subscriber *sub)
{
char check='n'; //定义check并初始化'n',用于控制循环
/*保证输入的用户名字是非空的*/
while(check=='n')
{
fflush(stdin); //清除标准输入流stdin
printf("\n请输入用户名字(不超过30字符): ");
scanf("%s",sub->name);
if((strlen(sub->name))==0) //如果你输入的字符长度为0
printf("\n\t名字是必输的"); //就提示"名字是必输的"
else //如果输入的字符长度不为0
check='y'; //就让check上放'y',表示名字已输成功
}
/*保证输入的地址是非空的*/
check='n';
while(check=='n')
{
fflush(stdin); //清除标准输入流stdin
printf("\n请输入用户地址(不得超过50个字符): ");
scanf("%s",sub->address);
if((strlen(sub->address))==0) //如果你输入的字符长度为0
printf("\n\t地址是必输的"); //就提示"地址是必输的"
else //如果输入的字符长度不为0
check='y'; //就让check上放'y',表示名字已输成功
}
/* 保证输入的电话号码是非空的*/
check='n';
while(check=='n')
{
fflush(stdin); //清除标准输入流stdin
printf("\n请输入电话号码: ");
scanf("%ld", &sub->telno);
if(sub->telno<2000000 || sub->telno>4999999)
printf("\n\t用户的电话号码必须是在2000000与4999999之间");
else
check='y'; //就让check上放'y',表示名字已输成功
}
}
/*下面函数的功能是:查看所有用户的详细资料*/
void viewdir()
{
FILE *fp;
struct subscriber viewsub;
int i=0, readctr=0;
int size_s=sizeof(struct subscriber); //计算出存储一个结构所需的字节大小
if((fp=fopen("telefon.txt", "r"))==NULL) //如果以只读的模式打开telefon.txt文件不成功
{
printf("\t电话目录文件打开不成功\n\n");
}
/*不管打开成功还是不成功*/
readctr=fread(&viewsub, size_s, 1, fp); //并且首先读取第一条记录
system("cls"); //调用系统的清屏指令
printf("\n\t电话目录文件中的记录如下:\n\n");
printf("条款\t姓名\t\t地址\t电话号码\n");
while(readctr==1) //然后再循环读到最后一条
{
i++;
printf("第%d条:\t%s\t\t%s\t%ld\n", i, viewsub.name, viewsub.address, viewsub.telno);
readctr=fread(&viewsub, size_s, 1, fp); //继续读取下一条
}
printf("\n");
fclose(fp); //关闭文件
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -