【C语言--------文件操作】

本文详细介绍了C语言中文件的概念、类型(程序文件和数据文件)、二进制文件和文本文件的区别、文件的打开与关闭、顺序读写(如fgetc/fputc等)、随机访问(如fseek/ftell)以及文件读取结束的判断方法。此外,还提及了ANSIC标准的缓冲文件系统原理。
摘要由CSDN通过智能技术生成

一.文件的概念

为什么使用文件?

如果没有文件,我们写的程序数据是存储在电脑的内存中的,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。

什么是文件?

磁盘(硬盘)上的文件就是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件

和数据文件(从文件功能的角度来分类的)。


程序文件:程序文件包括源程序文件(后缀为.c),目标文件(windows环境下为,obj),可执行程序(windows环境下为.exe)。

数据文件:文件的内容不一定是程序,而是程序运行时的读写数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

二.二进制文件和文本文件

二进制文件:数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件。

文本文件如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

      一个数据在文件中的存储:字符型数据在内存中都是以ASCII形式存储的,数值类型既可以字符类型数据的存储方式,也可以采用二进制的存储方式。

三.文件的打开和关闭

         在学习文件的打开和关闭之前,我们得先了解流和标准流。

       

          程序中数据需要输出到各种外部设备,也需要从各种外部设备输入数据,不同的外部设备的输入和输出的操作不相同,为了方便对于各种设备的操作,我们就抽象出了流这个概念。我们可以将流想象成流淌着的字符的河。


        标准流:在C语言程序启动的时候,默认打开了三个流。

stdin-标准输入流,在大多数的环境中,从键盘输入,scanf函数就是从你标准输入流中读取数据。

stdout-标准输出流,在大多数据环境下,输出至显示器界面,printf函数就是将信息输出到标准输出流当中。

stderr-标准错误流,大多数环境中输出到显示器界面。

以上这三个流的类型都是FILE*,通常称为文件指针(文件类型指针)。

C语言中就是通过FILE*的文件指针来维护流的各种操作的。通过文件指针就可以间接找到与他相关联的文件。

在文件读写之前,应该先打开文件,在结束之后关闭文件。

//打开文件
FILE* fopen(contst char* filename, const char* mode);
//关闭文件
FILE* fclose(const char* filename);

mode表示文件的打开模式,"r"(只读),"w"(只写),"a"(追加),"rb"(只读),"wb"(只写)等。

同时也要注意如果指定文件不存在的可能出错。

#include <stdio.h>
int main()
{
	FILE* pfile;
	//打开文件
	pfile = fopen("myfile.txt", "w");
	//文件操作
	if (pfile != NULL)
	{
		fputs("fopen example", pfile);
		fclose(pfile);
	}
	return 0;
}

四.文件的顺序读写

fgetc——字符输入函数。(适用于所有输入流)

fputc——字符输出函数。(适用于所有输出流)

fgets——文本输入函数。(适用于所有输入流)

fputs——文本输出函数。(适用于所有输出流)

fscanf——格式化输入函数。(适用于所有输入流)

fprintf——格式化输出函数。(适用于所有输入流)

fread——二进制输入。(文件输入流)

fwrite——二进制输出。(文件输出流)

上面所说的适用于所有输入流指的是一般适用于标准输入流和其他输入流(如文件输入流);所有的输出流指的是一般适用于标准输出流和其他输出流(如文件输出流)。

五.文件的随机读写

1.fseek

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。

int fseek(FILE* stream, long int offset, int origin);

例子:

#include <stdio.h>
int main()
{
	FILE* pfile;
	pfile = fopen("example.txt", "wb");
	fputs("This is an apple.", pfile);
	fseek(pfile, 9, SEEK_SET);
	fputs("sam", pfile);
	fclose(pfile);
	return 0;
}

2. ftell

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

long int ftell(FILE* stream);

例子:

#include <stdio.h>
int main()
{
	FILE* pfile;
	long size;
	pfile = fopen("myfile.txt", "rb");
	if (pfile == NULL)
		perror("error opening file");
	else
	{
		fseek(pfile, 0, SEEK_END);
		size = ftell(pfile);
		fclose(pfile);
		printf("size of myfile.txt:%ld bytes.\n",size);
	}
	return 0;
}

 rewind

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

void rewind(FILE*stream)

例子:

#include <stdio.h>
int main()
{
	int n;
	FILE* pfile;
	char buffer[27];

	pfile = fopen("myfile.text", "w+");
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pfile);
	rewind(pfile);

	fread(buffer, 1, 26, pfile);
	fclose(pfile);

	buffer[26] = '\0';
	printf(buffer);

	return 0;
}

六.文件读取结束

feof的作用

当文件读取结束的时候,判断读取结束的原因是否为:遇到文件末尾结束。

PS:不能用feof的返回值来判断文件是否结束。

1.文本文件是否读取结束

判断返回值是否为 EOF (fgetc)或者NULL(fgets)

例如:

fgetc 判断是否为EOF

fgets 判断是否为NULL.

eg:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int c;
	FILE* fp = fopen("test.txt", "r");
	if (!fp)
	{
		perror("file opening failed");
		return EXIT_FAILURE;
	}
	//fgetc当读取失败的时候或者遇到文件结束的时候,都会返回EOF
	while ((c = fgetc(fp) != EOF))  //标准C   I/O读取循环
	{
		putchar(c);
	}
	//判断是什么原因结束的
	if (ferror(fp))
		puts("I/O error when reading");
	else if (feof(fp))
		puts("End of file reached successfully");
	fclose(fp);
	return 0;
}

2.二进制文件的读取结束判断

判断返回值是否小于实际要读取的个数。

例如:

fread判断返回值是否小于实际要读取的个数。

eg:

#include <stdio.h>
enum
{
	SIZE = 5
};
int main(void)
{
	double a[SIZE] = { 1.,2.,3.,4.,5. };
	FILE* fp = fopen("test.bin", "wb");//必须用二进制
	fwrite(a, sizeof(*a), SIZE, fp);
	fclose(fp);

	double b[SIZE];
	fp = fopen("test.bin", "rb");
	size_t ret_code = fread(b, sizeof(*b), SIZE, fp);//读double 的数组
	if (ret_code)
	{
		puts("Array read successfully ,contents:");
		for (int i = 0; i < SIZE; i++)
			printf("%f ", b[i]);
		putchar('\n');
	}
	else
	{
		if (feof(fp))
			printf("error reading test .bin:unexpecxted end of file \n");
		else if (ferror(fp))
			perror("errror reading test.bin");
	}
	fclose(fp);
}

七.文件缓冲区

ANSIC标准采用 “缓冲文件系统” 处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。

从   内存   向    磁盘  输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。

如果从   磁盘   向   计算机     读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。

缓冲区的大小根据C编译系统决定的。

C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。

如有错误还望指出!

优质内容不断更新!! 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小峰编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值