C语言学习小结_10文件操作

本次总结的几个知识点
1、为什么使用文件
2、什么是文件
3、文件的打开和关闭
4、文件的顺序读写
5、文件的随机读写
6、文件的分类
7、文件读取结束的判定
8、文件缓冲区


1、为什么使用文件?
我们用c写一个通讯录的小应用的时候,当通讯录程序退出的时候,其中的数据就不存在了,等下次运行程序的时候又要重新录入,这样使用是不是很难受,那么能不能数据放到可以永久存储的地方呢?这就涉及到了数据持久化的问题,比如把数据存储得到磁盘或者数据库等。
使用文件我们可以将数据直接放到电脑的硬盘上,做到了数据的持久化。
2、什么是文件?
文件 = 内容 + 属性
在程序设计中,按照功能分类分为:程序文件和数据文件
2.1、程序文件
程序文件以.c结尾的,.obj结尾的,.exe结尾的。
2.2、数据文件
文件的内容不一定是程序,而是程序运行时读写的数据比如程序运行时候需要从中读取数据的文件,或者输出内容的文件。
2.3、文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
3.文件的打开和关闭
3.1文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如:文件的名字、文件状态、及文件的当前位置等。)这些信息保存在一个结构体变量中,该结构体的类型是由系统声明的,取名FILE.
例如FILE* pf;
定义pf是一个指向FILE类型数据的指针变量(结构体指针)。通过该文件信息区中的信息就能访问该文件。也就是说通过文件指针变量能够找到与它关联的文件。
文件=文件内容+文件属性
3.2
文件在读写之前应该先打开文件,在使用结束后应该关闭文件。
在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
用fopen来打开文件,fclose关闭文件
在这里插入图片描述

int main()
{
    
    
	FILE* pf = fopen("myfile.txt", "a");
	if (pf == NULL)
	{
    
    
		printf("File open error!\n");
		system("pause");
		return 1;
	}
	else{
    
    
		fputs("不是个梦!", pf);
		fclose(pf);
	}
	system("pause");
	return 0;
}

第一个形参为文件名,第二个为打开方式打开方式可以参考http://www.cplusplus.com/reference/cstdio/fopen/?kw=fopen
4、文件的顺序读写
字符输入输出函数:fgetc/fputc
文本行输入输出函数:fgets/fputs
格式化输入输出函数:fscanf/fprintf
二进制输入输出:fread/fwrite
我们可以用fprintf模拟printf
c语言会默认打开3个标准输入输出流,其类型也为FILE* 分别为:
stdin------->标准输入
stdout----->显示器
stderr------>显示器
一切皆为文件。

int main()
{
    
    
	fprintf(stdout, "chenzhihao is %s\n", "xiao ke ai!");
	system("pause");
	return 0;
}

5、文件的随机(位置)读写
fseek:根据文件的位置和偏移量来定位文件指针
ftell:返回文件相对于起始位置的偏移量
rewind:让文件读写的位置回到文件的起始位置。
具体可以参考如下:
http://www.cplusplus.com/reference/cstdio/fseek/?kw=fseek
6、文件的分类
根据数据的组织形式,数据文件被成为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加以转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码形式存储,则需要在村塾前转换。以ASCII码的形式存储的文件就是文本文件。
7、文件读取结束的判定
被错误使用的feof
牢记:在文件的读取过程中,不能用feof函数的返回值直接用来判断文件是否结束,而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件的结尾结束。
1)文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)
即:
fetc判断是否为EOF
fgets判断是否返回值为NULL
2)
二进制文件读取是否结束的判断是:判断返回值是u否小于要读取的个数。
fread判断返回值是否小于实际要读的个数
文本文件的代码如下:

int main()
{
    
    
	FILE* pf;
	int n = 0;
    pf = fopen("czh.txt", "r");
	if (NULL == pf){
    
    
		puts("File Open error!");
	}
	else{
    
    
		while (fgetc(pf) != EOF){
    
    
			n++;
		}
		//程序走到这里证明跳出循环,也就是文件读取结束,然后要feof判断
		//读取结束的原因
		if (feof(pf)){
    
    
			printf("文件总字符数为:%d\n", n);
		}
		else{
    
    
			puts("End of file is not reached!");
		}
		fclose(pf);
	}


	system("pause");
	return 0;
}

二进制文件的例子:

#define SIZE 10
int main()
{
    
    
	//二进制文件文件的读写
	double a[SIZE] = {
    
     3.10, 3.11, 3.12, 3.13, 3.14, 3.15, 3.16, 3.17, 3.18, 3.19 };
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL){
    
    
		puts("File open error!");
	}
	else{
    
    
		fwrite(a, sizeof(double), SIZE, pf);
		fclose(pf);
	}
	pf = fopen("data.txt", "rb");
	if (pf == NULL){
    
    
		puts("File open error!");
	}
	else{
    
    
		double b[3] = {
    
     0.0 };//缓冲区
		while (1){
    
    
		   size_t s=fread(b, sizeof(double), 3, pf);
		   if (s < 3){
    
    
			   break;
		   }
		   //对读到的元素进行操作
		}
		if (feof(pf)){
    
    
			puts("read file of end....!");
		}
		/*while (fread(b, sizeof(double), 3, pf)>0)
		{
			for (int i = 0; i < 3; i++){
				printf("%f\n", b[i]);
			}
		}*/
		fclose(pf);
	}
	system("pause");
	return 0;
}

或者:

int main()
{
    
    
	//二进制文件文件的读写
	double a[SIZE] = {
    
     3.10, 3.11, 3.12, 3.13, 3.14, 3.15, 3.16, 3.17, 3.18, 3.19 };
	FILE* pf = fopen("data.txt", "wb+");
	if (pf == NULL)
	{
    
    
		puts("File open error!");
	}
	else
	{
    
    
		fwrite(a, sizeof(double), SIZE, pf);
		//int pos_0 = ftell(pf);
		//printf("pos_0 = %d\n", pos_0);
		rewind(pf);//让文件读取位置回到其实位置,避免重新关闭和打开
		//int pos_1  = ftell(pf);
		//printf("pos_1 = %d\n", pos_1);
		double b[3] = {
    
     0.0 };//读缓冲区
		while (1)
		{
    
    
			size_t s = fread(b, sizeof(double), 3, pf);
			if (s < 3)
			{
    
    
				break;
			}
		}
		if (feof(pf))
		{
    
    
			puts("End of file is reached!\n");
		}
		else
		{
    
    
			puts("file read error!");
		}
		fclose(pf);
	}
	
	system("pause");
	return 0;
}

8.文件缓冲区
c程序默认提供了缓冲机制,所谓缓冲机制就是缓冲区,缓冲区本质上是一块内存,它的存在价值是提高效率,你可以把它理解成快递。
常见的缓冲机制有:1)无缓冲 2)行缓冲 3)全缓冲
行缓冲:以特殊符号作为缓冲区刷新的标志如“\n”,
全缓冲:把缓冲区加满才刷新,强制刷新,程序退出。
显示器文件是行缓冲和无缓冲
普通文件是全缓冲

猜你喜欢

转载自blog.csdn.net/CZHLNN/article/details/110238501
今日推荐