c语言 - 文件操作知识点总结

(目录因为排版出了点问题不能准确移动到对应位置就不弄了)

1.什么是文件,为什么要使用文件

使用文件的原因:

  • 我们在运行程序的时候,产生的数据是存放在内存中的,当程序退出时,内存中的数据就不存在了,当我们想把数据长久保存的时候,一般是把数据存放在磁盘文件或存放到数据库中。
  • 使用文件我们可以将数据直接存放到电脑的硬盘上,做到数据的持久化。

什么是文件:

  • 一般来说,磁盘上的文件就是我们常说的文件。但是在程序设计中,我们常说的文件分为程序文件数据文件(从文件功能的角度来分类)。

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

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

  • 在之前我们使用的输入输出函数都是以终端为对象的,也就是从终端的键盘输入数据,显示结果到显示器上。有时候我们也会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。
  • 文件名:一个文件要有一个唯一的文件标识,方便用户识别和使用。

文件名包含三个部分:文件路径+文件名主干+文件后缀

2.文件的打开和关闭

1.文件指针:缓冲文件系统中,关键的概念是文件类型指针,简称文件指针。

  • 每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件名,文件的状态及当前文件的位置等)。这些信息保存在一个结构体变量中。该结构体在系统中是有声明的,取名为FILE。
  • 每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不比关心其中的细节。
  • 一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更方便。

FILE* pf;//文件指针变量

  • 定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的信息区。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

2.文件的打开和关闭

  • 我们在操作文件的时候总是要先打开文件,最后再关闭文件的。
  • 在编写程序的时候,打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。ANSIC规定使用fopen函数来打开文件,fclose来关闭文件。

打开文件:FILE * fopen(const char * filename,const char * mode);

参数:(文件(相对路径或者绝对路径),文件打开方式)它的返回类型是FILE*所以在接收的时候也要用一个FILE*的指针来接收,打开成功返回的是相关文件信息的起始地址,打开失败返回空指针。

关闭文件: int fclose(FILE * stream);

参数:(接收此文件起始地址的指针)

举个例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//操作文件
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

这里由于没有创建这个文件所以返回我们的错误信息。

文件的打开方式有很多种,这里就不一一总结了。(图片借用一下别人的)

下面是顺序读写的一些函数:

 读取文件叫输入,写文件叫做输出,如下图:

 所有输出\入流:它适用于我们的文件和标准输出\入流。

 例子:

这是向文件写入字符

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//写文件
	fputc('b', pf);//fputc函数写入一个字符
	fputc('i', pf);
	fputc('t', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 我们可以看到文件按顺序写入了这三个字符。

这是向文件读取字符

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 由于我们之前写入了bit,所以现在按顺序读取到了bit。

一次写入一行数据:

int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (NULL == pf)
	{
		perror("fopen");
		return -1;
	}
	//写文件,写一行数据
	fputs("hello world\n", pf);
	fputs("lllllllllll\n", pf);
	//读一行数据
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

这里我们写入了两行数据。

 下面是读取一行数据:

int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return -1;
	}
	//读文件,一次读一行数据
	char arr[20] = { 0 };
	fgets(arr, 5, pf);//一次读取五个字符到arr数组中,实际读取四个最后一个是'\0',若读取长度超过则补'\0'
	printf("%s\n", arr);
	fgets(arr, 5, pf);
	printf("%s\n", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 由于末尾要加'\0',所以每次读取到的都是输入读取数字-1个数据。

后面的函数就不再举例了。

对比一组函数:

 对于其他函数我们都已经了解过了,这里对sscanf和sprintf这两个函数举例说明一下:

struct S
{
	int n;
	double d;
	char name[10];
};
int main()
{
	char arr[100] = { 0 };
	struct S tmp = { 0 };
	struct S s = { 100,3.14,"zhangsan" };
	//把一个格式化的数据转换成字符串
	sprintf(arr, "%d %lf %s", s.n, s.d, s.name);
	//打印
	printf("%s\n", arr);
	//从arr中的字符中提取一个格式化的数据
	sscanf(arr, "%d %lf %s", &(tmp.n), &(tmp.d), &(tmp.name));
	printf("%d %lf %s", tmp.n, tmp.d, tmp.name);
	return 0;
}

4.文件的随机读写

1.fseek

int fseek(FILE* stream, long int offset, int origin);(文件,起始位置,偏移量)

2.ftell

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

long int ftell ( FILE  *  stream );

3.rewind

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

void  rewind  (  FILE  *  stream );

例子:

我们向文件写入一个字符串"abcdef",然后进行操作

int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return -1;
	}
	//读文件
	//随机读写
	//第一次读取'c'
	fseek(pf, 2, SEEK_SET);
	int ch = fgetc(pf);//指针开始是指向a的,两个偏移量指向c
	printf("%c\n", ch);//c
	//读取'b'
	fseek(pf, -2, SEEK_CUR);
	ch = fgetc(pf);//读取完c后面指针已经指向了d所-2个偏移量就能读取到b
	printf("%c\n", ch);//b
	//计算文件指针相对于起始位置的偏移量
	int ret = ftell(pf);
	printf("%d\n", ret);
	//让文件指针回到起始位置
	rewind(pf);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

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

  • 根据数据的组织形式,数据文件被称为文本文件或者二进制文件
  • 数据在内存中以二进制的形式储存,如果不加转换的输出到外存(外部存储器,比如硬盘),就是二进制文件
  • 字符一律以ASCII形式存储,数值型数据既可以用ASSCII形式存储,也可以使用二进制形式存储。
  • 比如整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(vs2013)。

例子:

int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen");
		return -1;
	}
	int a = 10000;
	//以2进制的形式写文件
	fwrite(&a, 4, 1, pf);//(从哪里开始写数据,每个元素多少个字节,要写多少个元素,数据写到哪里去)
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

我们可以在源文件的现有项里找到data.txt文件以二进制的形式打开查看,可以看到它在内存中的存放,而且还是小端字节序的顺序,字节序没有发生变化。

 6.文件读取结束的判定

被错误使用的feof:

不是用来判断文件是否读取结束的,不能用feof函数的返回值直接用来判断文件是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

例如:

代码举例:

int main()
{
	int c;//int,非char,要求处理EOF
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return -1;
	}
	//fgetc当读取失败的时候或者遇到文件结束的时候都会返回EOF
	while ((c = fgetc(pf)) != EOF)
	{
		putchar(c);
	}
	//判断读取结束的原因
	if (ferror(pf))
	{
		puts("读取时发生错误");
	}
	else if (feof(pf))
	{
		puts("读取成功");
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

 

总结:

 7.文件缓冲区

在前面就提到了“缓冲文件系统”,ANSIC标准就是采用"缓冲文件系统"处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据c编译系统决定的。

例子:

#include<stdio.h>
#include<windows.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	fputs("abcedf", pf);//现将代码放在输出缓冲区
	printf("睡眠10秒-已经写数据了,打开data.txt文件,发现文件没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
	//fflush在vs2019会吃回车符
	printf("再睡眠10秒-此时,再次打开data.txt文件,文件有内容了\n");
	Sleep(10000);
	fclose(pf);//在关闭文件的时候,也会刷新缓冲区
	pf = NULL;
	return 0;
}

总结: 

因为有缓冲区的存在,c语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。

  • 18
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
简介: C语言是编程语言中的一朵奇葩,虽已垂垂老矣,但却屹立不倒,诞生了数十年,仍然是最流行的编程语言之一。C语言看似简单,却不易吃透,想要运用好,更是需要积淀。本书是一本修炼C程序设计能力的进阶之作,它没有系统地去讲解C语言的语法和编程方法,而是只对C语言中不容易被初学者理解的重点、难点和疑点进行了细致而深入的解读,揭露了C语言中那些鲜为普通开发者所知的秘密,旨在让读者真正掌握C语言,从而编写出更高质量的C程序代码。 全书一共11章:第1章重点阐述了C语言中不易被理解的多个核心概念,很多初学者在理解这些概念时都会存在误区;第2~8章对预处理、选择结构和循环结构的程序设计、数组、指针、数据结构、函数和文件知识点的核心问题和注意事项进行了讲解;第9章介绍了调试和异常处理的方法及注意事项;第10章对C语言中的若干容易让开发者误解误用的陷阱知识点进行了剖析;第11章则对所有程序员必须掌握的几种算法进行了详细的讲解;附录经验性地总结了如何养成良好的编码习惯,这对所有开发者都尤为重要。 本书主要内容:  堆和栈、全局变量和局部变量、生存期和作用域、内部函数和外部函数、指针变量、指针数组和数组指针、指针函数和函数指针、传址和传值、递归和嵌套、结构体和共用体、枚举、位域等较难理解的核心概念的阐述和对比;  预处理中的疑难知识点,包括文件的包含方式、宏定义及其常见错误解析、条件编译指令和#pragma指令的使用等;  if、switch等选择结构语句的使用注意事项和易错点解析;  for、while、do while等循环结构语句的使用注意事项和易错点解析;  循环结构中break、continue、goto、return、exit的区别;  一维数组、二维数组、多维数组、字符数组、动态数组的定义和引用,以及操作数组时的各种常见错误解析;  不同类型的指针之间的区别,以及指针的一般用法和注意事项;  指针与地址、数组、字符串、函数之间的关系,以及指针与指针之间的关系;  枚举类型的使用及注意事项,结构体变量和共用体变量的初始化方法及引用;  传统链表的实现方法和注意事项,以及对传统链表实现方法的颠覆;  与函数参数、变参函数、函数调用、函数指针相关的一些难理解和容易被理解错的知识点解析;  文件和指针的使用原则、技巧和注意事项;  函数调用和异常处理的注意事项和最佳实践;  与strlen、sizeof、const、volatile、void、void*、#define、typedef、realloc、malloc、calloc等相关的一些陷阱知识点的解析;  时间复杂度、冒泡排序法、选择排序法、快速排序法、归并排序法、顺序排序法、二分查找等常用算法的详细讲解;  良好的编码习惯和编程风格。
第一章 计算机基础知识 1、1946年2月15日世界上第一台电子计算机ENIAC〔埃尼阿克在美国宾州大学研制成功。 2、计算机发展史: 第一代:电子管计算机 采用电子管为基本元件,设计使用机器语言或汇编语言。要用于科学和工程计算 第二代:晶体管计算机 采用晶体管为基本元件,程序设计采用高级语言,出现了操作系统,应用到数据和事物处理 及工业控制等领域 第三代:中小规模集成电路计算机 采用集成电路为基本元件,应用到文字处理、企业管理和自动控制等领域 第四代:大规模、超大规模集成电路计算机 采用大规模集成电路为主要功能元件,在办公自动化、电子编辑排版等领域大显身手。 3、计算机的特点 〔1运算速度快 〔2运算精度高 〔3存储能力强 〔4逻辑判断能力强 〔5可靠性高 4、计算机的分类 5、计算机的应用领域 6、计算机的发展趋势 智能化 巨型化 微型化 网络化 多媒体化 7、计算机硬件系统 〔冯。诺伊曼机构 计算机硬件系统由五个基本部分组成, 控制器 运算器 包括算术运算和逻辑运算 存储器 存放程序和数据 输入设备 键盘、鼠标、扫描仪、数码相机等 输出设备。 显示器、打印机、绘图仪 控制器和运算器构成了计算机硬件系统的核心——中央处理器CPU〔Central Processing Unit。 通常把控制器、运算器和内存储器称为主机。 8、计算机指令定义 指令是对计算机进行程序控制的最小单元,是一种采用二进制表示的命令语言。一条指令 通常由两个部分组成,即操作码和操作数。 9、指令的执行过程。 10、什么是计算机软件 计算机软件是计算机系统中与硬件相互依存的另一部分,它是包括程序,数据及其相关文 档的完整集合。 11、计算机软件的分类 计算机软件一般可以分为系统软件和应用软件两大类。 12、系统软件分类 1、操作系统 windows 、linux、unix 等 2、编程软件 汇编语言、高级语言、机器语言、C语言、C++、java、C#等 3、数据库软件 SQL Server、Oracle、Mysql和Visual FoxPro等。 13、应用软件分类〔软件名称自己总结 办公应用 平面设计 视频编辑与后期制作 网站开发 辅助设计 三维制作 多媒体开发 程序设计 14、相关定义 操作系统是最基本最重要的系统软件,用来管理和控制计算机系统中硬件和软件资源的大 型程序,是其他软件运行的基础。 数据库管理系统DBMS〔DataBase Management System是数据库系统的核心,由一组用以管理、维护和访问数据的程序构成,提供了一个 可以方便地、有效地存取数据库信息的环境。 15、计算机组成由五部分组成 主机、显示器、键盘、鼠标、外部设备 16、主机的组成部分 CPU INTER和AMD 内存 内存储器和外存储器〔ROM和RAM的区别 主板 支持硬件正常运行的平台 硬盘 笔记本硬盘、台式机硬盘、服务器硬盘。转速、硬盘的三个接口:IDE、SATA、SCSI 光驱 CD-ROM DVD-ROM DVD+-RW 显卡 独立显卡和集成显卡 硬盘、光盘、U盘都属于外部存储器。 〔1随机存储器〔RAM。随机存储器也叫读写存储器.其特点是:存储的信息既可以读出,又 可以向内写入信息,断电后信息全部丢失。 〔2只读存储器〔ROM.只读存储器的特点:存储的信息只能读出,不能写入,断电后信息也 不丢失。 17、衡量一台微型计算机的主要性能指标包括 主频 、字长内存容量和存取周期、高速缓冲存储器〔Cache、总线速度 18、键盘〔考点:四个区自己整理 19、鼠标 分类:无线、有线、蓝牙 操作:选择、单击、双击、拖动、右键单击 20、计算机辅助工程 计算机辅助设计〔CAD 计算机辅助制造〔CAM 计算机集成制造系统〔CIMS 计算机辅助求解〔 CAE 计算机辅助工艺过程设计〔CAPP 21、数据库 定义:数据库〔Database是按照数据结构来组织、存储和管理数据的仓库 发展阶段:人工管理阶段、文件系统阶段、数据库系统阶段、高级数据库阶段。 22、编程语言的发展 第一代语言--机器语言 第二代语言--汇编语言 第三代语言—面向过程的高级语言。如:C语言、Pascal 等。 第四代语言--面向对象的高级语言。如:C+、C#、Java、Visual Basic等。 第二章 计算机病毒与防治 1、定义: 计算机病毒〔Computer Virus是指:能通过某种途径隐藏在计算机的存储介质〔或程序内,本身具有传染性,对 计算机系统具有破坏作用的一组程序或指令的集合。 2、计算机病毒的特性 传染性、潜伏性、破坏性、隐蔽性、可激发性 3、传播途径 <1>通过软盘 <2>通过硬盘 <3>通过光盘 <4>通过网络 4. 计算机病毒的分类 引导型病毒、文件型病毒、混合型病毒 5、计算
C语言是一种广泛应用于计算机科学和软件开发的编程语言。它具有强大的功能和灵活性,适用于开发各种类型的应用程序。 C语言专题精讲篇是一个对C语言进行深入学习和讲解的系列文章或课程。它汇总了C语言相关的重要知识点和技巧,旨在帮助学习者更好地理解和运用C语言。 这个专题中的笔记涵盖了C语言的各个方面,包括基本语法、数据类型、运算符、流程控制、函数、数组、指针、结构体、文件操作等。通过系统性的学习和总结,这些笔记可以帮助学习者逐步掌握C语言的核心概念和常用技巧。 在这个专题中,学习者可以学到如何编写简单的C程序,如何使用变量和运算符进行计算,如何使用条件和循环语句控制程序流程,如何使用函数进行代码的模块化,如何使用数组和指针进行数据的处理,如何使用结构体组织复杂数据,如何进行文件的读写等等。 C语言专题精讲篇的目的是帮助学习者全面、深入地了解C语言的各个方面,并能够独立编写和调试简单到中等难度的C程序。通过反复实践和练习,学习者可以逐渐提高自己的编程能力,并为进一步学习更高级的编程语言打下坚实的基础。 总之,C语言专题精讲篇的笔记汇总是一份重要的学习资料,可以帮助学习者系统地学习和掌握C语言的基础知识和常用技巧,为他们未来的编程之路打下坚实的基石。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值