⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 电话目录系统(二进制形式).cpp

📁 用C语言编写的一些源码示例
💻 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 + -