文件操作(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;
}
相关推荐
UestcXiye13 分钟前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk14 分钟前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*16 分钟前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue17 分钟前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man19 分钟前
【go从零单排】go语言中的指针
开发语言·后端·golang
好奇龙猫1 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
霁月风1 小时前
设计模式——适配器模式
c++·适配器模式
sp_fyf_20241 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
萧鼎2 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸2 小时前
【一些关于Python的信息和帮助】
开发语言·python