文件操作(2)(C语言版)

文件的随机读写:

fseek函数:

前面讲解了顺序读写的相关函数,这里介绍一些可以**"指哪写哪的函数"**

有三个参数:

1、文件的地址

2、相对于第三个参数origin偏移的位置

3、起始位置(有三种)

第一种:SEEK_SET(开头)

第二种:SEEK_CUR(当前位置)

第三种:SEEK_END(结尾)

cpp 复制代码
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcdef", pf);

	fclose(pf);
	pf = NULL;
	return 0;
}

可以通过fseek改变光标位置,而且是覆盖改写

什么意思呢?

如以下代码:

cpp 复制代码
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcdef", pf);
	fseek(pf, 2, SEEK_SET);//从头开始往后两个位置
	fputs("aa", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

还可以这样改:

cpp 复制代码
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcdef", pf);
	fseek(pf, 2, SEEK_SET);//从头开始往后两个位置开始
	fputs("aa", pf);
	fseek(pf, 3, SEEK_CUR);//从当前位置开始
	fputs("kikll", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

ftell函数:

返回文件指针相对于起始位置的偏移量

cpp 复制代码
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("abcdef", pf);
	fseek(pf, 2, SEEK_SET);//从头开始往后两个位置
	fputs("aa", pf);
	int ret = ftell(pf);
	printf("%d\n", ret);
	fclose(pf);
	pf = NULL;
	return 0;
}

rewind函数:

让文件指针的位置回到文件的起始位置

cpp 复制代码
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w+");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[27];
	char a = 0;
	for (a = 'A'; a <= 'z'; a++)
	{
		fputc(a, pf);
	}
	rewind(pf);
	fread(arr, 1, 26, pf);
	fclose(pf);
	pf = NULL;
	arr[26] = '\0';
	printf("%s\n", arr);
	return 0;
}

**文件读取结束的判定

到此为止讨论了所有文件的相关函数及操作,但是有一点我们还是有点不清楚,一个函数读取文件什么时候停止呢?停止的标志是什么呢?

那如果读取文件中途读取失败又会怎么样,返回的值类型是什么?

接下来就详细探究探究以上函数什么时候读取结束?

feof函数:

feof函数可以检查并判断文件是否为正常结束。

当读取到文件末尾时结束读取,feof会返回一个非零的值,但是读的时候也会有异常结束的时候 ,这时候返回的值就是0。

用feof判断文件是否结束还是失败是不行的。

所以这里就需要用到每个函数读取是否结束的返回值进行判断!

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets ) 例如: fgetc 判断是否为 EOF . fgets 判断返回值是否为 NULL .

  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。 例如: fread判断返回值是否小于实际要读的个数。

拷贝一份文件

cpp 复制代码
int main()
{
	FILE* pf = fopen("test.txt", "w+");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int a = 0;
	for (a = 'A'; a <= 'Z'; a++)
	{
		fputc(a, pf);
		if (a % 5 == 0)
		{
			fputc('\n', pf);
		}
	}
	rewind(pf);//找到起始位置
	FILE* pf1 = fopen("cool.txt", "w");
	if (pf1 == NULL)
	{
		perror("fopen");
		fclose(pf);
		pf = NULL;
		return 1;
	}
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		fputc(ch,pf1);
	}
	fclose(pf1);
	pf1 = NULL;
	fclose(pf);
	pf = NULL;
	return 0;
}

改进通讯录(可以保存在文件中)

之前写的通讯录经过多次修改,现在可以动态化存储,单数唯一的缺点是,当运行结束后,所有的信息也会跟着销毁,不会被存储起来,现在有办法将其存储在文件中,为此要用的时候,可以打开,这样存储的信息就不会丢失了。

结束之前将信息存入文件

我们用fwrite写入文件,fread读取文件内容。

cpp 复制代码
void savecontact(con* pc)
{
	FILE* pf = fopen("contact.txt", "wb");//二进制打开文件输出
	if (pf == NULL)
	{
		perror("fopen");
		return ;
	}
	int i = 0;
	for (i = 0; i < pc->num; i++)
	{
		fwrite(pc->contact + i,sizeof(per),1,pf);
	}
	fclose(pf);
	pf = NULL;
}

因为fwrite返回的值为读取的值,一次性读取的值我们可以进行设置

参数num为每次读取的值,当读取的值比设置的小,则返回之际读取的个数。

所以选择用while循环一次一次读取!!

开始时写入文件中保存的内容

cpp 复制代码
void inputcontact(con* pc)
{
	FILE* pf = fopen("contact.txt","rb");
	if (pf == NULL)
	{
		perror("inputcontact");
		return;
	}
	//录入信息
	per tmp = { 0 };
	while (fread(&tmp, sizeof(per), 1, pf))
	{
		checkcapacity(pc);
		pc->contact[pc->num] = tmp;
		pc->num++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
相关推荐
水蓝烟雨几秒前
1931. 用三种不同颜色为网格涂色
算法·leetcode
Hello eveybody2 分钟前
介绍一下背包DP(Python)
开发语言·python·动态规划·dp·背包dp
AI进化营-智能译站18 分钟前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
iCxhust22 分钟前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
晨曦夜月26 分钟前
map与unordered_map区别
算法·哈希算法
Morwit28 分钟前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen8740 分钟前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
莎士比亚的文学花园43 分钟前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
图码1 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
U盘失踪了1 小时前
python curl转python脚本
开发语言·chrome·python