| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 【手把手带你进阶】C语言:文件操作 -> 正文阅读 |
|
[C++知识库]【手把手带你进阶】C语言:文件操作 |
【手把手带你进阶】C语言:文件操作哈喽!大家好呀~好久不见啦! 回头一看,发现关于C语言的内容我们已经讲得差不多了,还剩下文件操作和程序的编译这两部分。 其中文件的操作比较简单,在工作中用得也比较少,虽然如此,我们也不能不学它呀~毕竟这也是C语言的一部分,不学它好像不太完整,而且万一以后要用到怎么办呢?所以我们还是老老实实地把文件的操作过一遍吧! 为什么使用文件在之前编写的程序中,我们会发现在程序运行的过程中,我们当下输入的信息在程序结束之后就不再保存了,当下一次再运行程序的时候,上次输入的信息就没有任何记录。 如果我们希望每次运行程序时输入的信息都被保存下来,这时候我们就可以把信息写入文件中,因为文件是存储在磁盘上的,所以程序结束后,程序运行的内存还给操作系统了,但是文件里面的内容却不会被抹去(除非我们自己执行了删除操作),从而达到保存信息的目的。 所以我们说,使用文件可以让我们将数据直接存放在电脑的硬盘上,从而做到数据的持久化。 什么是文件磁盘上的文件都是文件。 我们打开电脑C盘、D盘或者E盘,我们可见的里面存放的所有东西都是文件。 程序文件我们平常码代码得到的后缀为.c(源程序文件) / .obj (Windows环境下的目标文件)/ .exe(Windows环境下的可执行程序)等的文件都称为程序文件。 数据文件而我们运行程序的时候,可能需要把一些信息写到文件里面或者从文件中读取数据。这些文件用来存储程序运行时读写的数据的文件就是数据文件,后缀为.txt。 那么今天本文讨论的都是数据文件。 在之前的学习中,我们总是把信息通过键盘输入,再输出到屏幕上。而今天,我们操作的对象是文件,则我们是把信息输出到磁盘上,或者是把数据从磁盘上读取到内存中使用,所以这里处理的就是磁盘上的文件。 文件名那么一个文件到底是怎么描述的呢? 当然是借助于文件名了。 一个文件要有一个唯一文件标识,以便于我们来识别和引用。 而我们通常利用文件名来对文件进行识别和引用。 一个文件的文件名包含3个部分:文件路径+文件名主干+文件后缀
为了方便,通常我们就把文件标识成文文件名。 文件的打开和关闭文件指针首先我们要对文件进行定位,这时候我们需要借助文件指针。 这是缓冲文件系统中一个关键的概念,称为“文件类型指针”,简称为“文件指针”。 当我们操作文件的时候,我们首先要打开文件,而当我们打开文件的时候,系统就在内存中开辟了一个相应的文件信息区,用来存放诸如文件名、文件状态、文件当前位置等的信息,这些信息都被保存在一个结构体变量中,由系统进行声明,取名为FILE。 所以只要我们打开文件,内存中就会相应地生成一个文件信息区,从而把文件和程序关联上。 以下给出VS2013环境下的文件结构体。 我们作为文件的使用者,不必关心文件信息区中的文件是如何填充的。 程序一般通过一个FILE指针来维护这个FILE结构的变量,而我们通过这个FILE指针来找到文件信息区,通过文件信息区把我们和文件关联起来,从而对文件进行操作。 文件的打开和关闭那么知道了文件指针之后,我们应该如何打开文件呢? 实际上,在编写程序的时候,我们打开文件的同时,系统都会返回一个FILE*的指针,该指针指向该文件,由此建立了指针和文件的关联。 那么我们到底怎么打开文件呢? 我们可以cplusplus网站上查一下这个函数。
在网页下方我们可以看到fopen函数给我们提供的打开模式有以下几种: 下面给出更全的文件使用方式: 而关闭文件用到的函数是fclose。 那么这时候如果我们把data.txt文件放到别的路径下,程序还能不能打开它呢? 当然可以,但是我们要向程序提供文件的路径。 假如我把文件放到桌面上。 注意要避免路径中的斜杠和字符结合形成转义字符,所以我们要在有斜杠的地方再加上一个斜杠,防止转义。 注意,如果我们只提供了文件的主干名给fopen,则相当于是提供了相对路径,而如果是把文件路径传给了fopen,则是提供了绝对路径。 大家可以看到,上面的表格中最后有一栏,如果指定的文件不存在。
文件的顺序读写当我们了解了如何打开和关闭文件之后,接下来我们就要看看到底应该如何来读写文件。 当我们再程序中要把数据写到文件当中去时,我们把写文件的操作称为输出,相应地,我们把从文件中读取数据到内存中称为输入。 明白了以上逻辑之后,我们依次来看下面这些文件读写函数:
接下来我们就用这两个函数来对文件分别就进行写和读。 fputc 字符输出函数首先我们去cplusplus网站上看一下fputc这个函数应该怎么用。
下面我们用代码实现。
另外,只要我们运行了C的程序,就默认打开了3个流:
只要打开了这三个流,我们打开程序之后就可以直接进行数据的输入或者输出了。 而上述fputc函数是适用于所有输出流的,即我们既可以把数据输出到文件中,也可输出到屏幕上等等。 下面我们通过程序来看看。 fgetc 字符输入函数下面我们来看看fgetc函数。
fputs 文本行输出函数
下面看代码: 现在打开abc.txt文件,可以看到被写入的字符串。 fgets 文本行输入函数
下面看代码和程序运行结果: fprintf 格式化输出函数
fscanf 格式化输入函数同理,我们也将fscanf和scanf函数对比着看。 所以其实反过来读文件也是类似的方法,只是这次我们是把读到的信息放到变量s中去。
fwrite 二进制输出函数
fread 二进制输入函数
比较下面三个输入输出函数
下面讲一下sprint和sscanf函数。 我们还是先到cplusplus网站上分别查一下这两个函数。 文件的随机读写上面我们介绍的函数都是按照顺序从前到后进行读写的,我们称为顺序读写。那么如果我想从文件的中间输入或者输出某个数据,这时就涉及到了文件的随机读写。 下面我们依次来看一下这些函数。 fseek首先打开桌面上的abc.txt文件。我们看到里面有两行字符串,当我们在程序中打开文件的时候,pf默认是指向文件内容中的第一个位置,现在我们希望直接读到中间的’o’字符,我们应该怎么做呢?
老规矩,还是去cplusplus网站上看一下这个函数的使用指引吧。 函数中的三个参数分别是文件指针,偏移量和起始位置。 当我们刚打开文件的时候,不对文件进行任何操作,这时候文件指针指向文件的起始位置,则这时SEEK_SET和SEEK_CUR一样。
答案是-4,因为当我们读完’o’之后,指针又向后走了一步,所以如果要读‘e’,则偏移量为4。
但是有时候我们可能并不知道,或者不便于得到指针的偏移量,所以下面我们需要了解帮助我们或者指针偏移量的函数。 ftellftell可以告诉我们文件指针相对于起始位置的偏移量。
rewind如果我们已经读了很多内容,文件指针已经走了很远之后,我们希望文件指针恢复到起始位置,这时候就要用到rewind函数。
答:fopen是C语言提供给我们的一个函数,但是它为什么可以调用存储在硬盘上的文件呢? 文本文件和二进制文件我们知道,数据在内存中是以二进制的形式存储的,如果对其不加转换地输出到外存(硬盘)中,这样的文件就是二进制文件。 而如果在存储到外存中之前,数据被转换成ASCII码的形式,则这些以ASCII字符形式存储的文件被称为文本文件。 所以根据文件的组织形式,数据文件被分为文本文件和二进制文件。 我们可以看到,当我们打开一个文本文件,里面存储的信息是我们可以读懂的。 那么一个数据在内存中是怎么存储的呢? 首先,字符是用ASCII形式存储的,而数值型数据在内存中既可以用ASCII的形式存储,也可以用二进制的形式存储。 假设我们有一个整数10000,如果这个数以ASCII的形式输出到磁盘中,则在磁盘中占5个字节(10000共5个字符),而如果以二进制的形式存储,则在磁盘中占4个字节(一个int类型的大小)。 下面我们用代码将10000以二进制的形式写到文件中去。
首先进入VS2019,在源文件中把data.txt添加进去。 文件结束的判定那么我们如何知道一个文件是否读取结束了呢? 前面我们一共讲了11个有关文件读写的函数,而其中有关文件读取的有如下几个:
下面我们去cplusplus中查看这些函数的返回值。 首先我们看fgetc这个函数的返回值。 所以,我们可以通过判断fgetc函数的返回值是否是EOF来判断文件是否读取结束。
那么当一个文件读取结束之后,我们应该如何判断它是因为错误而结束的还是遇到文件尾结束的呢? 这时候我们就可以用到ferror和feof这两个函数,并且在前面对每个函数返回值的查阅中,我们都看到了对于遇到错误和文件末尾结束时是如何设置它们的。 下面我们举两个栗子~ 文件缓冲区标准C中采用“缓冲文件系统”来处理数据文件。
注意两个问题:
同时这也进一步说明为什么我们写完文件要关闭文件,因为关闭文件时会刷新缓冲区,这样可以确保我们结束程序的时候数据确实写到文件中去了。 以上就是C语言中关于文件的操作详解啦~ 其实对于文件的操作在工作中的使用并不多,但是作为一名程序员,这些基本的操作我们怎么能不知道呢?所以还是要好好掌握,万一哪一天用上了呢? 好啦!C语言的进阶只剩下最后一个部分啦~ 博主尽量快点更新,大家一起期待吧! 本文的代码已经上传到Gitee啦~欢迎取阅哦! https://gitee.com/fang-qiuhui/my-code/blob/my_code/blog_2021_10_26_file/blog_2021_10_26_file.c |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 6:08:45- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |