C学习笔记-结构体与二进制文件增删改查

使用结构体整理数据,然后利用二进制存储文件,这样存储的文件类似于数据库,可以实现文件的增删改查

定义结构体

struct student
{
	unsigned int ID;
	char name[20];
};

创建二进制文件

int main(int argc, char *args[])
{
	struct student st[10] = { {1, "a"}, {2, "b"}, {3, "c"}, {4,"d"}, {5, "e"}, {6, "f"}, {7, "g"}, {8, "h"}, {9, "i"}, {10, "j"} };

	FILE *p = fopen("a.dat", "wb");
	if (p == NULL)
	{
		return 0;
	}
	fwrite(st, sizeof(struct student), 10, p);//写入10个struct student大小的内容
	fclose(p);
	return 0;
}

读取内容

int main()
{
	FILE *p = fopen("a.dat", "rb");
	if (p == NULL)
	{
		return 0;
	}

	struct student st;
	memset(&st, 0, sizeof(st));
	while (fread(&st, sizeof(st), 1, p))//循环读取文件所有内容
	{
		printf("ID = %u, name = %s
", st.ID, st.name);
	}
	fclose(p);
	return 0;
}

替换内容

int main(int argc, char *args[])//替换第3个元素
{
	struct student st = { 3, "zhang" };

	FILE *p = fopen("a.dat", "rb+");
	if (p == NULL)
	{
		return 0;
	}
	fseek(p, sizeof(st)* 2, SEEK_SET);//从文件开始位置向后移动两个struct student大小
	fwrite(&st, sizeof(struct student), 1, p);//将st写入文件
	fclose(p);
	return 0;
}

根据ID查找内容

int main()//根据用户输入查找指定ID号的同学
{
	FILE *p = fopen("a.dat", "rb");
	if (p == NULL)
	{
		return 0;
	}
	struct student st;
	while (1)//循环读取用户键盘输入ID号
	{

		printf("input ID:");
		unsigned int ID = 0;
		scanf("%u", &ID);
		if (ID == 0)
			break;
		clock_t ct = clock();//得到程序当前运行时间,单位毫秒
		fseek(p, sizeof(st)* (ID - 1), SEEK_SET);//根据用户输入ID好,将位置移动到指定位置

		memset(&st, 0, sizeof(st));
		fread(&st, sizeof(st), 1, p);//读取指定位置内容
		ct = clock() - ct;
		printf("%d
", ct);//将代码执行时长打印到屏幕,单位:毫秒
		printf("ID = %u, name = %s
", st.ID, st.name);
	}
	fclose(p);
	return 0;
}

插入内容

其主要思想是全部查出,然后添加,再写入

void insert(struct student array[], int len)
{
	for (int i = len - 1; i >= 2; i--)
	{
		array[i + 1] = array[i];
	}
}

int main()//读取结构体二进制文件所有内容
{
	FILE *p = fopen("a.dat", "rb");//只读方式打开二进制文件
	if (p == NULL)
	{
		return 0;
	}
	struct student *pst = calloc(100, sizeof(struct student));
	int index = 0;
	while (fread(&pst[index++], sizeof(struct student), 1, p) > 0);//循环读取文件所有内容
	insert(pst, index);
	pst[2].ID = 100;
	strcpy(pst[2].name, "zhao");
	for (int i = 0; i < index + 1; i++)
	{
		printf("ID = %u, name = %s
", pst[i].ID, pst[i].name);
	}
	fclose(p);
	p = fopen("a.dat", "wb");
	if (p == NULL)
	{
		return 0;
	}
	fwrite(pst, sizeof(struct student), 11, p);
	fclose(p);
	free(pst);
	return 

例子

将txt文本文件转为二进制文件,并随机编号

#include <stdio.h>
#include <time.h>

struct student 
{
	unsigned int ID;
	char name[20];
};

void write_dat()
{
	srand((unsigned int)time(NULL));//生成一个随机种子
	FILE *p1 = fopen("student.txt", "r");//以只读方式打开student.txt文件
	FILE *p2 = fopen("student.dat", "wb");//以只读方式打开student.txt文件
	while (!feof(p1))
	{
		struct student st = { 0, "" };
		fgets(st.name, sizeof(st.name), p1);
		size_t len = strlen(st.name);
		if (st.name[len - 1] == '
')
		{
			st.name[len - 1] = 0;
		}
		st.ID = rand();
		fwrite(&st, sizeof(struct student), 1, p2);
	}
	fclose(p1);
	fclose(p2);
}




int main()
{
    write_dat();
	FILE *p = fopen("student.dat", "rb");
	if (p == NULL)
	{
		return 0;
	}
	struct student st;
	while (fread(&st, sizeof(st), 1, p) > 0)
	{
		printf("ID = %u, name = %s
", st.ID, st.name);
	}
	fclose(p);
	return 0;
}