C语言文件详解(超级详细,记得收藏~~~)

2023-11-12

什么是文件

磁盘上的文件是文件。

在程序设计中,我们一般读的文件有两种:程序文件 和 数据文件

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

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

文件名

一个文件要有一个唯一的文件标识,以便于用户识别与引用。

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

c:\code\test.txt

文件类型

文本文件:肉眼看得懂的东西

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

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

文件指针

文件类型指针(文件指针)

每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息(如文件名字,文件状态,文件当前的位置)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名为FILE.

vs2019编译环境中提供的 stdio.h头文件中有以下的文件类型声明。

#ifndef _FILE_DEFINED
    #define _FILE_DEFINED
    typedef struct _iobuf
    {
        void* _Placeholder;
    } FILE;
#endif

不同C编译器的FILE类型包含内容大同小异。

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。

一般都是通过FILE的指针来维护这个FILE结构的变量。

FILE *pf;

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

总结:每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息,这个相关信息是个结构体,使用typedef类型重新定义,也就是FILE

文件的打开与关闭

在打开文件的同时,会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

ANSIC规定使用fopen来打开文件,fclose来关闭文件。

相对路径写法(当前代码所在路径下)

… 表示上一级路径

. 表示当前路径

FILE* p = fopen("../test.txt","r");    //打开当前路径低下 的test文件

绝对路径写法(明确指出)

fopen("C:\\2012_code\\84\\test\\test1.txt ""r");

打开方式

文件使用方式 含义 如果指定文件不存在
“r”(只读) 为了输入数据,打开一个已存在的文本文件 出错
“w”(只写) 为了输出数据,打开一个文本文件 建立一个新的文件(销毁原来的文件信息)
“a”(追加) 向文本文件尾添加数据 出错
“rb”(只读) 为了输入数据,打开一个二进制文件 出错
“wb”(只写) 为了输出数据,打开一个二进制文件 建立一个新的文件(销毁原来的文件信息)
“ab”(追加) 向一个二进制文件添加数据 出错
“r+”(读写) 为了读和写,打开一个文本文件 出错
“w+”(读写) 为了读和写,建立一个新的文件 建立一个新的文件
“a+”(读写) 打开一个文件,在文件尾进行读写 建立一个新的文件

如果文件打开失败,返回空指针NULL

在这里插入图片描述

FILE* pf = fopen("text.txt","r");
if(pf == NULL)
{
    printf("%s\n",strerror(errno));
    return 0;
}
fclose(pf);
pf = NULL;

关闭文件时是值传递,不会改变文件本身。

文件的顺序读写

结合MSDN食用更好

功能 函数名 适用于
字符输入函数 int fgetc( FILE * stream); 所有输入流
字符输出函数 int fputc(int c, FILE* stream); 所有输出流
文本行输入函数 char *fgets(char* string, int n, FILE* stream) 所有输入流
文本行输出函数 int fputs(const char* string, FILE* stream) 所有输出流
格式化输入函数 fscanf把文件假想成黑色的对话框。和普通的scanf相比,前面多了一个指向文件信息的指针。 所有输入流
格式化输出函数 fprintf 和普通的printf相比,前面多了一个指向文件信息的指针。(把数据放到文件里了) 所有输出流
二进制输入 fread : 返回类型是读了几个元素 文件
二进制输出 fwrite 文件

键盘stdin和屏幕stdout都是外部设备, stdinstdout都是FILE类型的

键盘 - 标准输入设备; 屏幕 - 标准输出设备

是一个程序默认打开的两个流设备。

关于fread的返回值

fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.

对比一组函数

scanfprintf:针对标准输入流、标准输出流的格式化输入、输出语句

fscanffprintf:针对所有输入流、所有输出流的格式化输入、输出语句

sscanfsprintf:

sscanf :从字符串中读取格式化的数据

Read formatted data from a string.

int sscanf( const char *buffer, const char *format [, argument ] ... );

sprintf:把格式化的数据存储到字符串中

Write formatted data to a string.

int sprintf( char *buffer, const char *format [, argument] ... );

用途:记录日志

但是文件不安全,不够高效 ------>>>> 数据库 MySQL ?

使用文件的格式:

打开文件 — 安全检查 ---- 操作 ---- 关闭文件

文件随机读取

fseek根据文件指针的位置和偏移量定位文件指针。

fseek
Moves the file pointer to a specified location.

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

offset: 偏移量(单位字节)   origin:文件指针当前位置

文件当前位置的三种形式:

SEEK_CUR

Current position of file pointer

SEEK_END

End of file

SEEK_SET

Beginning of file

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

ftell
    
Gets the current position of a file pointer.

long ftell( FILE *stream );

应用

int main()
{
    FILE* pf = fopen("test.txt","r");
    if(pf == NULL)
    {
		printf("%s\n",strerror(errno));
    }
    //1.定位文件指针
    fseek(pf, 2, SEEK_CUR);
    //2.读取文件
    int ch = fgetc(pf);
    
    printf("%c",ch);
    
    fclose(pf);
    pf=NULL;
	return 0;
}

rewind:让文件指针回到起始位置

rewind
    
Repositions the file pointer to the beginning of a file.

void rewind( FILE *stream );

文件结束判断

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

Return Value

The feof function returns a nonzero value after the first read operation that attempts to read past the end of the file. It returns 0 if the current position is not end of file. There is no error return.

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

  1. 文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)

    ​ fgetc判断是否是EOFfgets判断返回值是否为NULL

  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。比如:通过fread判断返回值是否小于实际要读的个数。

perror()

函数直接先打印你放在括号里面的字符串,然后接着打印冒号和错误信息。

ferror()

Return Value

If no error has occurred on stream, ferror returns 0. Otherwise, it returns a nonzero value.

应用

int main()
{
	FILE* pf = fopen("test.txt","r");
    if(pf == NULL)
    {
        perror("open file test2.txt");
        return 0;
    }
    //读文件
    int ch = 0;
    while((ch = fgetc(pf)) != EOF)
    {
		putc(ch);
    }
    if(ferror(pf))
    {
		printf("error\n");
    }
    else if(feof(of))
    {
		printf("end of file");
    }
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言文件详解(超级详细,记得收藏~~~) 的相关文章

  • 高级 Win32 图像文件 I/O?

    我想在 Windows C 应用程序中将图像文件读入内存 什么是一个相当简单的解决方案 也许类似于 IOS 提供的UIImage 我希望支持合理数量的文件格式 我需要为图像处理的位图提供一些低级访问权限 我在互联网上阅读了很多内容 看起来
  • 测试 hdf5/c++ 中的组是否存在

    我正在打开一个现有的 HDF5 文件来附加数据 我想向那个叫做的小组保证 A存在以供后续访问 我正在寻找一种简单的方法来创建 A有条件地 如果不存在则创建并返回新组 或者返回现有组 一种方法是测试 A存在 我怎样才能高效地做到这一点 根据
  • 实体框架代码优先 - 在另一个文件中配置

    使用 Fluent API 将表到实体的映射分开的最佳方法是什么 以便它全部位于单独的类中 而不是内联在 OnModelCreating 方法中 我目前在做什么 public class FooContext DbContext prote
  • 在 Windows Phone 上启动 pdf 文件时出现 System.Runtime.InteropServices.COMException

    我正在尝试使用我之前在另一个应用程序上使用过的以下工作代码打开 pdf 文件 但这一次 当流程到达此行时 我收到 System Runtime InteropServices COMException Windows System Laun
  • 浮点提升:stroustrup vs 编译器 - 谁是对的?

    在 Stroustrup 的新书 C 编程语言 第四版 第 10 5 1 节中 他说 在执行算术运算之前 整数提升用于从较短的整数类型创建整数 类似地 浮点提升是用于从浮点数创建双精度数 我用以下代码确认了第一个声明 include
  • Linq Where 本地计数器关闭在 VS watch 中的结果不同

    我尝试删除前 3 个元素array与 LinQWhere扩展功能 这是一个例子 var array new 1 2 3 4 5 6 7 8 9 var count 3 var deletedTest1 0 var test1 array W
  • 对数字进行向上和向下舍入 C++

    我试图让我的程序分别向上和向下舍入数字 例如 如果数字是3 6 我的程序应该四舍五入最接近的数字 4 如果该数字是3 4 它将向下舍入为 3 我尝试使用ceil库获取 3 个项目的平均值 results ceil marks1 marks2
  • 使用 VSTO 更改 Outlook 设置

    我刚刚花了大约 4 个小时试图弄清楚如何以编程方式检索 设置 Microsoft Outlook 2010 的 Outlook 设置 我所说的 设置 是指文件 选项 邮件下的设置 我想做的是检索用户设置的设置列表 自动化我们每天需要在某些消
  • 控制台应用程序 .net Core 2.0 的配置

    在 net Core 1 中我们可以这样做 IConfiguration config new ConfigurationBuilder AddJsonFile appsettings json true true Build 这样就可以使
  • C#:使用 System.Text 和 System.Text.RegularExpressions 之间的区别

    在 ASP NET C 应用程序中 我注意到为了使用 Regex 和 StringBuilder 我必须将两者都放在 using System Text using System Text RegularExpressions 从简单的角度
  • 如何在不使用reinterpret_cast的情况下使用dlsym()加载函数?

    我正在尝试使用 clang tidy 来强制执行 C 核心指南 虽然它确实有很多有效点 但有一件事我无法真正解决 dlsym 返回一个void 我需要以某种方式将其转换为正确的函数指针 为此 我使用reinterpret cast 由于指南
  • 抽象类和接口之间的区别[重复]

    这个问题在这里已经有答案了 可能的重复 接口与基类 https stackoverflow com questions 56867 interface vs base class 我不明白抽象类和接口之间的区别 我什么时候需要使用哪种字体
  • 使用 Linq 进行异步Where过滤

    我有一个List通过填充的元素async调用 WebService 没问题 我需要过滤该列表以便在应用程序视图上显示某些内容 我试过这个 List
  • 编写专门用于类及其子类的函数模板

    我正在尝试编写一个函数模板 一个版本应该用于不满足另一版本标准的所有类型 当参数是给定类的基类或该类本身时 应使用另一个版本 我尝试过超载Base 但是当类派生自Base 他们使用通用的 而不是特定的 我也尝试过这种 SFINAE 方法 s
  • OpenMP C 程序运行速度比顺序代码慢

    我是 OpenMP 的新手 正在尝试并行化 Jarvis 的算法 然而事实证明 与顺序代码相比 并行程序花费的时间要长 2 3 倍 难道问题本身就不能并行化吗 或者我并行化它的方式有问题 这是我针对该问题的 openMP 程序 其中有 2
  • 改进C++逐行读取文件的能力?

    我正在解析大约 500GB 的日志文件 我的 C 版本需要 3 5 分钟 我的 Go 版本需要 1 2 分钟 我正在使用 C 的流来流式传输文件的每一行以进行解析 include
  • 删除对象时指针自动指向空

    假设我有一个对象和其他几个不同类类型的对象中的 10 个指向它的指针 如果对象被删除 这些指针必须设置为空 通常我会将对象的类与具有指向它的指针的类互连 以便它可以通知它们它正在被删除 并且它们可以将它们的指针设置为空 但这也有一个负担 即
  • 如何使复选框不可选择?

    我想知道你是怎么做的CheckBox在c 中无法选择 我认为这会是类似 SetSelectable false 之类的东西 但我似乎看不到该方法 I found CanSelect但这似乎是只读属性 您可以设置自动检查 http msdn
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么
  • 最后从同一类中的其他构造函数调用构造函数

    我在这里读到可以调用另一个构造函数从同一类中的另一个构造函数调用构造函数 https stackoverflow com questions 829870 calling constructor from other constructor

随机推荐

  • 时间序列的特征工程——一些总结

    一个说法在最前面 创造新的特征是一件十分困难的事情 需要丰富的专业知识和大量的时间 机器学习应用的本质基本上就是特征工程 Andrew Ng 大佬整理的一个时间序列预测方法总结 时间序列预测方法总结 知乎 特征工程的流程介绍 关于做特征工程
  • Bi-LSTM原理及TensorFlow实现序列标注

    本文整理了Bi LSTM的原理 并在静觅博客静觅 TensorFlow Bi LSTM实现序列标注 的基础上对TensorFlow 搭建一个Bi LSTM来处理序列标注问题的代码进行了详细的注释 Bi LSTM理解 RNN的意思是 为了预测
  • oracle-04 分页查询

    原文转载自 https www cnblogs com wuxu p 11198764 html oracle的分页查询 使用 rownum关键字 oracle对外提供的自动给查询结果编号的关键字 与每行的数据没有关系 注意 rownum关
  • pytest

    1 概述 pytest是一个非常成熟的全功能的Python测试框架 主要特点有以下几点 1 简单灵活 容易上手 文档丰富 2 支持参数化 可以细粒度地控制要测试的测试用例 3 能够支持简单的单元测试和复杂的功能测试 还可以用来做seleni
  • 2021.11.18总结

    数据结构递归 进一步了解了什么是递归 什么时候使用递归 递归模型 递归出口 递归体 了解了如何去设计递归算法
  • MySQL数据库中的架构之内存架构

    MySQL5 5 版本开始 默认使用InnoDB存储引擎 它擅长事务处理 具有崩溃恢复特性 在日常开发中使用非常广泛 内存结构中 主要分为这么四大块儿 Buffer Pool Change Buffer Adaptive Hash Inde
  • 饥荒 服务器没有响应,饥荒服务器卡怎么办 饥荒服务器卡顿解决方法

    随着TGP版饥荒的发售 想必不少玩家都把这款游戏见捡起来摸了 一些玩家在和其他玩家联机进行游戏的时候出现了卡顿的现象 那么饥荒服务器卡怎么办呢 下面小编就为大家带来饥荒服务器卡顿解决方法 一起来看看吧 随着TGP版饥荒的发售 想必不少玩家都
  • hadoop的datanode启动不了

    启动hadoop 2 6遇到的datanode启动不了 分类 hadoop 2014 12 22 12 25 2678人阅读 评论 2 收藏 举报 hadoop 查看日志如下 2014 12 22 12 08 27 264 INFO org
  • c++(练习题)————无重复字符的最长子串

    题目描述 给定一个字符串 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc 所以其长度为 3 示例 2 输入 bbbbb 输出 1 解释 因为无重复字符的最
  • 解决vue项目中出现的console报错问题

    解决vue项目中出现的console报错问题 问题描述 在vue项目中 使用console log输出是总是会报错 使用如下 控制台报错如下 页面报错如下 vue项目中使用的版本如下 package json文件 产生原因 ESLint代码
  • C#中 ??、 ?、 ?: 、?.、?[ ]

    1 可空类型修饰符 引用类型可以使用空引用表示一个不存在的值 而值类型通常不能表示为空 例如 string str null 是正确的 int i null 编译器就会报错 为了使值类型也可为空 就可以使用可空类型 即用可空类型修饰符 来表
  • 缓存系列文章--8.热点key问题(mutex key)

    转载请注明出处哈 http carlosfu iteye com blog 2269678 一 引出热点key问题 我们通常使用 缓存 过期时间的策略来帮助我们加速接口的访问速度 减少了后端负载 同时保证功能的更新 一般情况下这种模式已经基
  • 2020-04-21

    实验2 3 1 求1到100的和 10分 本题要求编写程序 计算表达式 1 2 3 100 的值 输入格式 本题无输入 输出格式 按照以下格式输出 sum 累加和 代码 int main int i 0 int sum 0 for i 0
  • Numpy--布尔索引

    布尔索引 布尔索引是通过相同数组上的True还是False来进行提取的 提取的条件可以有多个 那么如果有多个 可以使用 来代表且 用来代表或 如果有多个条件 那么每个条件要使用圆括号括起来 布尔运算也是矢量的 比如以下代码 a1 np ar
  • IOS拉伸圆角图片

    UIImage buttonImageNormal UIImage imageNamed whiteButton png UIImage stretchableButtonImageNormal buttonImageNormal stre
  • String,StringBuffer,StringBuilder三者的异同?

    String StringBuffer StringBuilder三者的异同 String 不可变的字符序列 底层使用char 存储 StringBUffer 可变的字符序列 线程安全的 效率低 底层使用char 存储 StringBuil
  • 刀片服务器做虚拟机,刀片服务器Vmware虚拟化部署经验分享(初稿).docx

    HP C7000刀片服务器虚拟机部署经验分享 本文主要介绍一台新的 HP C7000 刀片服务器从上架加电到进行虚拟机部署的主要步骤 第一部分 为刀片系统配置远程管理 首先附 C7000刀片服务器各组件示意图一张 注意图中的 Insight
  • 华为云服务器免费用,CDN免费用,数据库免费用,免费免费,全场免费

    华为云免费专区 全场免费 自从华为云17年进军公有云市场以来 市场份额增长神速 20年华为云以高达259 6 的同比增长速度 已然稳定公有云市场前三的位置 但很多人依然没有试用过华为云的产品 即便性价比很高 也不敢贸然更换厂商 俗话说是骡子
  • 【ubuntu】Anaconda 安装+环境配置:pytorch1.5.0+torchvision0.6.0+cudatoolkit10.1

    1 正确安装anaconda 1 下载对应Anaconda版本 以Anaconda3 5 3 1 Linux x86 64 sh为例 Anaconda下载连接 2 命令安装 bash Anaconda3 5 3 1 Linux x86 64
  • C语言文件详解(超级详细,记得收藏~~~)

    什么是文件 磁盘上的文件是文件 在程序设计中 我们一般读的文件有两种 程序文件 和 数据文件 程序文件包括源程序文件 后缀为 c 目标文件 win下后缀为 obj 可执行文件 win下环境后缀为 exe 数据文件 文件的内容不一定是程序 而