C进阶:文件操作

C语言文件操作

什么是文件

磁盘上的数据是文件。

但是在程序设计中,我们一般谈的文件有两种:程序文件(例如.c,.h这一类编译,链接过程中的文件),数据文件。

程序文件

包括源程序文件(后缀为.c),目标文件(windows环境的后缀为.obj,linux环境的后缀为.o),可执行程序(windows的后缀为.exe,习惯上linux环境下没有后缀)。

数据文件

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

文件名

一个文件要有一个文件标识,以便用户识别和引用。

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

例如:c:\code\test.txt。

为了方便,文件标识通常被称为文件名

文件类型

根据数据的组织形式,数据文件被称为文本文件或者二进制文件

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

2.如果要求在外存中以Ascii码的形式存储,则需要在存储之前进行转换。以ASCII字符形式存储的形式就是文本文件。

3.字符一律以ASCII形式存储,数值型既可以用ASCII形式存储,也可以用二进制形式存储

如果有整数10000,如果以ASCII码的形式存储到磁盘,则在磁盘中占用五个字节,如果以二进制存入,则在磁盘中占用四个字节。下面来看一下为什么是这样存的。

再来看一下以二进制形式存入的代码:

#include<stdio.h>int main()
{int a = 10000;//创建一个文件指针,以只写的形式打开或创建test.txt,后面会讲FILE* pf = fopen("test.txt", "wb");//二进制的形式写入文件中fwrite(&a, 4, 1, pf);fclose(pf);pf = NULL;
}

 在vs中以二进制编辑器打开test.txt的结果如下:

 前面的00000000是没有意义的地址,而后面的数据确实是10000的16进制位。

文件指针

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

每个被使用的文件都在内存中开辟了一个相应的文件信息区。

打算读写一个文件时:

1.打开文件 2.被打开的文件就维护了一个文件信息区

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

一般都是通过FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

我们来创建一个FILE*指针变量:

FILE* pf;

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

比如:

文件的打开与关闭 

文件操作的基本步骤:打开文件->读写文件->关闭文件

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

ANSIC规定使用fopen函数来打开文件,fclose来关闭文件。(头文件为:stdio.h)

使用方式

FILE* fopen(const char* filename,//文件名称
const char* mode//文件的使用方式
)int fclose(FILE* stream);//文件指针

以下为文件的所有打开方式(注意当指定文件不存在时的情况):

v2-c4773117934a3d2d75abd7b6bbcd1a12_r.jpg (1118×613)

 举个小栗子:

#include <stdio.h>int main()
{FILE* pf;//test.txt为相对路径,表明这个文件就在程序内。pf = fopen("test.txt", "w");//如果文件指针pf不为真再进行操作if (pf != NULL){//文本行输出函数fputs,一会会讲。fputs("fopen example", pf);//关闭文件fclose(pf);//将文件指针置为空pf = NULL;}return 0;
}

文件的顺序读写

C语言程序只要运行起来,默认打开三个流(stream)

注:流的定义:文件中的流(stream)是指数据在输入和输出设备(例如硬盘、键盘、显示器等)与程序之间的传输通道。流可以被看作是一个字节序列的抽象,它将输入和输出抽象为一个连续的数据流,使得程序可以通过流来访问和处理文件的内容。

1.标准输入流 stdin FILE*:用于键盘接收输入数据。

2.标准输出流 stdout FILE*:用于向屏幕输出数据。

3.标准错误流 stderr FILE*:用于向屏幕输出错误信息。

 

 

重要函数的对比与使用

fgetc与fputc

1.函数原型:int fgetc(FILE* stream);

功能:用于读取文件fgetc 用于从指定的文件流(stream)中读取一个字符,并返回读取的字符的整数表示(ASCII码值)。如果到达文件末尾或出现读取错误,它会返回 EOF(End of File)。

2.函数原型:int fputc(int ch, FILE* stream);

功能:用于写入文件fputc 函数将指定的字符 ch 写入到指定的文件流 stream 中。如果成功写入,返回写入的字符;如果发生错误,返回 EOF(通常是 -1)。

fscanf与fprintf

fscanf 函数:

  • 函数原型:int fscanf(FILE *stream, const char *format, ...);

  • 功能:fscanf 从指定的文件流中读取数据,并根据指定的格式字符串进行解析。它类似于 scanf,但是它从文件中读取数据而不是从标准输入读取fscanf 返回成功读取和解析的项目数,如果发生读取错误或到达文件末尾,它会返回 EOF

2.fprintf 函数:

  • 函数原型:int fprintf(FILE *stream, const char *format, ...);

  • 功能:fprintf 向指定的文件流中写入数据,根据指定的格式字符串格式化数据并写入文件。它类似于 printf,但是将输出数据写入文件而不是标准输出fprintf 返回成功写入的字符数,如果发生写入错误,它会返回负值。

sscanf和sprintf

1.sscanf 函数:

  • 函数原型:int sscanf(const char *str, const char *format, ...);

  • 功能:sscanf 从指定的字符串 str 中读取数据,并根据指定的格式字符串进行解析。它类似于 scanf,但是从字符串中读取数据而不是从标准输入读取。sscanf 返回成功读取和解析的项目数。

2.sprintf 函数:

  • 函数原型:int sprintf(char *str, const char *format, ...);

  • 功能:sprintf 根据指定的格式字符串 format 将数据格式化输出到字符串 str 中。它类似于 printf,但是将输出数据写入到字符串而不是标准输出。sprintf 返回成功写入的字符数。

举个栗子:

#include <stdio.h>int main()
{char str[] = "20 20";int num1, num2;sscanf(str, "%d %d", &num1, &num2);printf("the two numbers are %d and %d", num1, num2);return 0;
}

结果:

 文件的随机读写

fseek函数:根据文件的起始位置和偏移量来定义文件指针.

int fseek(FILE* stream,//文件指针long int offset,//偏移量,是整数就正向偏移,是负数就负向偏移int origin//起始位置
//包括:SEEK_SET(文件起始位置),SEEK_CUR(文件指针当前位置),SEEK_END(文件结束位置)
)

举个例子:

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

可见:在字符串偏移量为9的位置之后将字符串"sam"插入了进去。

pftell函数:计算文件指针相当于起始位置的偏移量。

long int ftell(FILE* stream) 

举个例子:

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

这里还是读的原来的字符串this is asampple ,所以算出的结果为16.

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

void* rewind(FILE* stream).

#include <stdio.h>int main()
{int n;FILE* pf;//创建一个字符串char buffer[27];//为了读和写建立了一个新的文件myfile.txtpf = fopen("myfile.txt", "w+");//利用文件指针向文件依次写入A到Z26个字符for (n = 'A'; n <= 'Z'; n++){fputc(n, pf);}//让文件返回到起始位置rewind(pf);//又再次在文件开始位置读取26个字符并放入buffer中fread(buffer, 1, 26, pf);fclose(pf);pf = NULL;//第27个元素设为'\0',以便截断字符串buffer[26] = '\0';puts(buffer);return 0;
}

文件结束的判定

被错误使用的feof

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

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

那么应该怎样判断文件是否结束呢?

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

例如:fgetc判断是否为EOF。

          fgets判断返回值是否为NULL。

2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数

例如:fread判断返回值是否小于要读的数。

正确的使用方法如下:

文本文件

#include <stdio.h>
#include <stdlib.h>int main()
{int c;//注意int ,不是char,要求处理EOF。FILE* fp = fopen("test.txt", "r");if (fp == NULL){perror("File opening filed!");return;}//fgetc当读取失败的时候或者遇见文件尾的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF){putchar(c);}//判断是什么原因结束的if (ferror(fp)){puts("\nI\O error when reading");}else if (feof(fp)){puts("\nEnd of file reached successfully");}fclose(fp);fp = NULL;return 0;
}

好了,文件指针就讲到这里,欢迎各位大佬指点!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10020.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重生之我要学C++第四天

这篇文章的主要内容是类的默认成员函数。如果对大家有用的话&#xff0c;希望大家三连支持&#xff0c;博主会继续努力&#xff01; 目录 一.类的默认成员函数 二.构造函数 三.析构函数 四.拷贝构造函数 五.运算符重载 一.类的默认成员函数 如果一个类中什么成员都没有&…

JavaWeb 速通HTTP

目录 一、HTTP快速入门 1.HTTP简介 : 2.HTTP请求头 : 3.HTTP响应头 : 二、HTTP响应状态码 1.基本介绍 : 2.常见状态码 : 3.状态码的分类 : 4.完整状态码汇总 : 三、HTTP请求包和响应包 1.请求包分析 : 1 GET请求 (1) 说明 (2) doGet返回数据给浏览器 (3) form表单提…

Hadoop生态体系-2

目录标题 1、MapReduce介绍2、数据仓库3、HIVE4、HQL4.1 hive读写文件机制4.2 Hive数据存储路径 1、MapReduce介绍 思想&#xff1a;分而治之 map:“分”&#xff0c;即把复杂的任务分解为若干个“简单的任务”来处理。可以进行拆分的前提是这些小任务可以并行计算&#xff0c…

C++ 函数重载

1.函数重载的概念 在C中可以为两个或两个以上的函数提供相同的函数名称&#xff0c;只要参数类型不同&#xff0c;或参数类型相同而参数个数不同&#xff0c;称为函数重载。 在C语言中实现int&#xff0c;char&#xff0c;double类型的比较大小函数&#xff1a; int my_max_…

【Kubernetes资源篇】ingress-nginx最佳实践详解

文章目录 一、Ingress Controller理论知识1、Ingress Controller、Ingress简介2、四层代理与七层代理的区别3、Ingress Controller中封装Nginx&#xff0c;为什么不直接用Nginx呢&#xff1f;4、Ingress Controller代理K8S内部Pod流程 二、实践&#xff1a;部署Ingress Control…

STM32 串口实验(学习一)

本章将实现如下功能&#xff1a;STM32通过串口和上位机对话&#xff0c;STM32在收到上位机发过来的字符串后&#xff0c;原原本本返回给上位机。 STM32 串口简介 串口作为MCU的重要外部接口&#xff0c;同时也是软件开发重要的调试手段&#xff0c;其重要性不言而喻。现在基本…

KMP算法的及其原理

KMP算法 首先 我们先了解一下 KMP算法的作用 str1 和str2 字符串 如果str1中包含str2 那么返回头位置 如果不包含返回-1 首先 我们先加入一个概念: 有一个next数组 next[i]的值为 str2 中 以i-1位置为结尾的字符串中 最长相同前缀后缀为多长(相同前缀后缀 不是对称 aba 中相…

uniapp 小程序如何从主包页面跳转到分包页面

在uniapp开发小程序的时候&#xff0c;“分包”概念一定要提前了解下&#xff0c;具体我就不多说了&#xff0c;自己看下关网的相关配置。 那么&#xff0c;如果从主包页面&#xff0c;跳转至分包的页面呢&#xff1f;如图所示 我的页面->详情页 在我的页面创建好自己的链…

ARM--LED灯点亮

LED1,LED2,LED3亮灯 .text .global _start_start: /**********LED1点灯--->PE10**************//*初始化RCC章节*/通过RCC_MP_AHB4ENSETR寄存器,使能GPIOs组控制器 0x500000A28[4] 1RCC_INIT: E组和F组一起使能ldr r0,0x50000A28 ldr r1,[r0]orr r1,r1,#(0x3 << 4)s…

vue3+ts+elementui-plus二次封装树形表格实现不同层级展开收起的功能

一、TableTreeLevel组件 <template><div classmain><div class"btns"><el-button type"primary" click"expandLevel(1)">展开一级</el-button><el-button type"primary" click"expandLevel(2…

13年测试老鸟,接口性能测试总结整理,据说这是全网最全的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试按照不同…

【云原生系列】openstack搭建过程及使用

目录 搭建步骤 准备工作 正式部署OpenStack 安装的过程 安装组件如下 登录页面 进入首页 创建实例步骤 上传镜像 配置网络 服务器配置 dashboard配置 密钥配置免密登录 创建实例 绑定浮动ip 免密登录实例 搭建步骤 准备工作 1.关闭防火墙和网关 systemctl dis…

抖音SEO源码开发指南:介绍如何开发抖音SEO源码的基本步骤和要点。

一、 抖音SEO源码开发指南&#xff1a; 确定目标&#xff1a;首先要明确开发抖音SEO源码的目标是什么&#xff0c;是提高搜索排名还是增加用户量等。根据不同的目标来制定开发策略和思路。 分析竞争&#xff1a;对于同类产品&#xff0c;要进行竞争分析&#xff0c;了解对手的…

在Mac系统下搭建Selenium环境并驱动Chrome浏览器

本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器&#xff0c;虽然会有坑&#xff0c;但是我们可以凭借敏捷的身手躲过。下面就开始吧&#xff1a; 安装selenium 打开终端 ->pip安装&#xff08;安装命令&#xff1a;pip3 install selenium&#xff09; 安装浏览…

如何在 SwiftUI 中使用 Touch ID 和 Face ID?

1. 需要通过指纹&#xff0c;面容认证后才能打开 App 2. 添加配置 需要向 Info.plist 文件中添加一个配置&#xff0c;向用户说明为什么要访问 添加 Privacy - Face ID Usage Description 并为其赋予值 $(PRODUCT_NAME) need Touch Id or Face ID permission for app lock 3. …

HTML不常用但是好用的标签

sub sup <p>这个文本包含 <sub>111</sub>文本。</p> <p>这个文本包含 <sup>上标</sup> 文本。</p>下标文本将会显示在当前文本流中字符高度的一半为基准线的下方&#xff0c;但是与当前文本流中文字的字体和字号都是一样的。…

Git竞合处理

Gitee新建一个代码仓库&#xff0c;clone到本地&#xff0c;模拟竞合的情况出现 这里仓库已经配好了ssh&#xff0c;所以没有添加账户绑定的步骤 clone到本地 模拟A同学Clone代码 git clone 项目地址新建一个文件&#xff0c;上传到仓库 push到仓库 代码仓库已经可以看到了…

HEVC网络适配层介绍

h265 的分层结构 分层结构的目的 ○ 网络类型多种多样&#xff0c;不同的网络环境具有不同的特性&#xff0c;压缩视频在其中进行传输必然会受到影响&#xff1b;比如不同网络的 MTU 有所不同&#xff1b; ○ 不同的应用场景对视频有不同的需求&#xff0c;视频业务会喜用不…

springboot快速整合腾讯云COS对象存储

1、导入相关依赖 <!--腾讯云COS--><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.0.1</version></dependency><dependency><groupId>com…

【矩特征】图像矩特征

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 cv2.moments() 矩特征 1. 正文 (1). 空间矩 零阶矩&#xff1a;m00一阶矩&#xff1a;m10,m01二阶矩&#xff1a;m20,m11,m02三阶矩&#xff1a;m30,m…