文件操作(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;
}
相关推荐
zander2587 分钟前
LeetCode 46. 全排列
算法·leetcode·深度优先
我命由我1234512 分钟前
Android 开发 - 广播组件(标准广播、有序广播、静态注册广播、分钟到达广播、网络变更广播...)
android·java·开发语言·网络·java-ee·android studio·android-studio
米码收割机35 分钟前
【Python】Python Django+Vue3校园自习室预约管理系统(源码+文档+PPT)【独一无二】
开发语言·python·django
AstartesEternal43 分钟前
python第二次作业(列表,字典)
开发语言·python
zh路西法44 分钟前
【Navigation2进阶】(十二):自主探索性能优化与 RIG 算法推导与 Nav2 插件实现
c++·dijkstra·ros2·rrt·navigation2·前沿探索
星恒随风1 小时前
C++ STL 详解:set 与 multiset 的使用、区间查询和算法应用
开发语言·c++·笔记·学习·算法
数聚天成DeepSData1 小时前
外贸海关进出口数据去哪免费下载?从统计到明细的查找指南
linux·服务器·开发语言·前端·网络·人工智能·自然语言处理
Lumos1861 小时前
《ESP32 物联网全栈实战-02》ESP-IDF 工程结构
算法
再卷也是菜1 小时前
C++11支持并发库
开发语言·c++
Lhan.zzZ1 小时前
QML 开发中的“陷阱”:动态模型更新时,ComboBox 索引为何总是失效?
开发语言·qt