文件没学懂没关系,我来教你快速学会文件

news2024/11/15 9:07:08

在这里插入图片描述

1. 什么是文件

文件通常是在磁盘或固态上的一段已经命名的存储区。C把文件看作是一系列连续的字节,每个字节都被单独读取。

在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)

1.1 程序文件

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

1.2 数据文件

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

1.3 文件名

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

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

例如:c:\code\test.txt

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

2. 文件的打开和关闭

2.1 文件指针

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

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

下面我们可以创建一个FILE*的指针变量:

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

通过文件指针变量能够找到与它关联的文件

2.2 文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件

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

2.2.1 fopen()函数

该函数声明在stdio.h中,它的第1个参数是待打开文件的名称,更确切地说是一个包含该文件名的字符串地址;第2个参数是一个字符串,指定打开文件的模式

模式字符串含义
“r”以读模式打开文件文件
“w”以写模式打开文件,把现有文件的长度截为0,如果文件不存在,则创建一个新文件
“a”以写模式打开文件,在现有文件末尾添加内容,如果文件不存在,则创建一个新文件
”r+“以更新模式打开文件(即可以读写文件)
“w+”以更新模式打开文件(即读和写),如果文件不存在,则将其长度截为0,;如果文件不存在,则创建一个新文件
“a+"以更新模式打开文件(即读和写),在现有文件的末尾添加内容,如果文件不存在,则创建一个新文件;可以读整个文件,但是只能从末尾添加内容
”rb”以读模式打开二进制文件
“wb”以写模式打开二进制文件,把现有文件的长度截为0,如果文件不存在,则创建一个新文件
”ab“以写模式打开二进制文件,在现有二进制文件末尾添加内容,如果二进制文件不存在,则创建一个新二进制文件
“rb+“以更新模式打开二进制文件(即可以读写二进制文件)
”wb+“以更新模式打开二进制文件(即读和写),如果二进制文件不存在,则将其长度截为0,;如果二进制文件不存在,则创建一个新二进制文件
”ab+“以更新模式打开二进制文件(即读和写),在现有二进制文件的末尾添加内容,如果二进制文件不存在,则创建一个新二进制文件;可以读整个二进制文件,但是只能从末尾添加内容

2.2.1 fclose()函数

fclose(fp)函数关闭fp指定的文件,必要时刷新缓冲区,对于较正式的程序,应该检查是否成功关闭文件。如果成功关闭,fclose()函数返回0,否则返回EOF

3. 文件的顺序读写

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文件行输入函数fgets所有输入流
文本行输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

4. 文件的随机读写

4.1 fseek

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

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

4.2 ftell

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

long int ftell (FILE * stream);

4.3rewind

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

void rewind (FILE *stream);

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

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

如果要求在外存上以ASCLL码的形式存储,则需要在存储前转换。以ASCLL字符的形式存储的文件就是文本文件

字符一律以ASCLL形式存储,数值型数据既可以用ASCLL形式存储,也可以使用二进制形式存储

6. 文件读取结束的判定

6.1 被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束,而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

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

例如:

  • fgetc判断是否为EOF
  • fgets判断返回值是否为NULL

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

例如:

  • fread判断返回值是否小于实际要读的个数

文本文件的例子:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if(!fp) {
        perror("File opening failed");
        return EXIT_FAILURE;
    }
    //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
    {
    	putchar(c);
    }
    //判断是什么原因结束的
    if (ferror(fp))
    	puts("I/O error when reading");
    else if (feof(fp))
    	puts("End of file reached successfully");
    fclose(fp);
}

二进制文件的例子:

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{
    double a[SIZE] = {1.,2.,3.,4.,5.};
    FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式
    fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin","rb");
    size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组
    if(ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
        putchar('\n');
    } else { // error handling
    	if (feof(fp))
    		printf("Error reading test.bin: unexpected end of file\n");
    	else if (ferror(fp)) {
    		perror("Error reading test.bin");
    	}
    }
    fclose(fp);
}

7. 文件缓存区

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

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
    FILE*pf = fopen("test.txt", "w");
    fputs("abcdef", pf);//先将代码放在输出缓冲区
    printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
    Sleep(10000);
    printf("刷新缓冲区\n");
    fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
    //注:fflush 在高版本的VS上不能使用了
    printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
    Sleep(10000);
    fclose(pf);
    //注:fclose在关闭文件的时候,也会刷新缓冲区
    pf = NULL;
    return 0;
}

这里可以得出一个结论:
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题。

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

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

相关文章

Spring Boot操作数据库学习之整合MyBatis

文章目录一 MyBatis简介二 配置数据源三 整合测试3.1 导入MyBatis依赖3.2 配置数据库连接信息application.yml3.3 使用idea测试数据库3.4 创建实体类【可以使用Lombok】3.5 创建实体类3.6 创建mapper目录以及对应的Mapper接口3.7 创建Mapper映射文件3.8 配置mybatis映射文件3.9…

第四十四章 动态规划——背包问题模型(一)

第四十四章 动态规划——背包问题模型&#xff08;一&#xff09;一、模型概述二、模型变形1、AcWing 423. 采药&#xff08;1&#xff09;问题&#xff08;2&#xff09;分析&#xff08;3&#xff09;代码2、AcWing 1024. 装箱问题&#xff08;1&#xff09;问题&#xff08;…

ESP8266 ArduinoIDE 物联网web客户端开发

一、使用 esp8266 实现 HTTP 客户端协议 在 arduinoIDE 中&#xff0c;并没有专门的 HTTP 协议客户端库。但是我们可以用 TCP 协议来自动手动实现。 1.1 HTTP 请求报文简介 所谓请求报文&#xff0c;即是基于 TCP/IP 协议发送的一串规范字符&#xff0c;这串规范字符描述了当…

liunx centos9安装nodejs并搭建vue 图文详解手把手教程

首先nodjs的官网找到liunx的安装包 https://nodejs.org/en/download/ 这里不推荐用源码安装&#xff0c;因为实在太慢&#xff0c;我安装时一下在不停安装连续15分钟都还在跑就是不知道什么原因 解压包 tar -xvf /root/node-v18.13.0-linux-x64.tar.xz设置全局 -s后面地址就是…

Android入门第59天-进入MVVM

什么是MVVM用“某大文豪亲”的话说&#xff1a;MVVM并不存在&#xff0c;只是xml里找控件找了太多了&#xff0c;自然而然就“找”出了一套共性。所以&#xff0c;MVVM只是包括了以下这些技术&#xff1a;DataBind&#xff1b;ViewModel双向绑定&#xff1b;Okhttp3retrofitrxj…

图解函数递归、数组详解

目录 一.修炼必备 二.图解递归的执行过程 三.数组 3.1 一维数组 3.2 二维数组 3.3 数组的共同问题 一.修炼必备 1.入门必备&#xff1a;VS2019社区版&#xff0c;下载地址&#xff1a;Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com) 2.趁手武…

视频文缩略图SDK:GleamTech VideoUltimate Crack

Video Reader and Thumbnailer for .NET Core 和 .网络框架 读取地球上的任何视频文件格式。逐帧读取视频文件。生成有意义的缩略图。 VideoUltimate是最快&#xff0c;最简单的.NET视频阅读器和缩略图器&#xff0c;可以读取任何视频文件格式 在地球上。它允许您逐帧读取视频…

C++ 一文解决 数据库ODB 安装/调试/使用的问题

引用&#xff1a; ODB Download (codesynthesis.com) Installing ODB on Linux/UNIX (codesynthesis.com) 缘起&#xff1a; 在开发过程中发现&#xff0c;现有的软件缺乏持久层&#xff08;Persistence Layer&#xff09;&#xff0c;即专注于实现数据持久化应用领域的某个…

广义零样本学习的转移增量

摘要&#xff1a;零样本学习&#xff08;ZSL&#xff09;是一种成功的从未知类中对对象进行分类的范例。然而&#xff0c;它在广义零样本学习&#xff08;GZSL&#xff09;设置中遭受严重的性能降级&#xff0c;即以识别来自可见类和不可见类的测试图像。在本文中&#xff0c;为…

C语言-qsort函数基本使用

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C/C】 先来看一下qsort函数的介绍&#xff1a; Compare 函数的返回值描述>0elem1将被排在elem2前面0elem1等于elem2<0elem1 将被…

LeetCode刷题模版:171-174、179

目录 简介171. Excel 表列序号172. 阶乘后的零173. 二叉搜索树迭代器174. 地下城游戏【未理解】179. 最大数结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,…

Redis学习【1】之Nosql概述

文章目录一 从技术发展探究使用Nosql的原因1.1 单机Mysql时代1.2 Memcached&#xff08;缓存&#xff09; MySQL 垂直拆分[读写分离]1.3 MySQL主从读写分离1.4 分表分库 水平拆分 Mysql 集群1.5 如今时代1.6 使用NoSQL的原因二 Nosql初识2.1 NoSQL的特点【解耦】三 NoSQL的四…

树状数组的原理和区间和

目录 一、前言 二、树状数组的原理 1、杂论 2、从二叉树到树状数组 3、神奇的 lowbit(x) 操作 4、tree[ ]数组&#xff1a;将一维信息转换为树形信息存储 5、基于 tree[ ] 的计算 6、tree[]的更新&#xff08;要加lowbit&#xff09; 三、树状数组的应用 1、单点修改…

流媒体方案之Nginx

1.Nginx可以作为流体服务器。2三种web服务器的比较3.推流端: FFmpeg使用RTMP协议向Nginx推流拉流端: •VLC播放器使用RTMP或HTTPFLV协议从Nginx拉流•浏览器使用HTTPFLV协议从Nginx拉流(安装flv.js)4.有两种方法&#xff1a;下载源码&#xff0c;手工编译使用Buildroot&#xf…

Redis分布式锁 | 黑马点评

目录 一、分布式锁概述 二、基于Redis的分布式锁 1、思路分析 2、初级版本 3、误删问题 4、改进分布式锁 5、原子性问题 6、使用Lua脚本解决原子性问题 7、setnx实现分布式锁存在问题 三、Redisson 1、Redisson快速入门 2、Redisson可重入锁原理 3、Redisson可重试…

从某一点出发沿任意一方向旋转矩阵计算思考与实现

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 上期讲到 绕任一向量旋转矩阵计算思考与实现 点击前往 点击前往 问题提出 之前讲到绕任一向量旋转矩阵实现&#xff0c;原来的向量都是从原点出发&#xff0c;现在把…

Ajax面试题目

更多Ajax面试题目可以查看专栏内容 1.AJAX应用和传统Web应用有什么不同&#xff1f; 传统的web前端与后端的交互中&#xff0c;浏览器直接访问Tomcat的Servlet来获取数据。Servlet通过转发把数据发送给浏览器。当我们使用AJAX之后&#xff0c;浏览器是先把请求发送到XMLHttpR…

Swift之struct二进制大小分析

随着Swift的日渐成熟和给开发过程带来的便利性及安全性&#xff0c;京喜App中的原生业务模块和基础模块使用Swift开发占比逐渐增高。本次讨论的是struct对比Class的一些优劣势&#xff0c;重点分析对包体积带来的影响及规避措施。 一、基础知识 1、类型对比 引用类型&#xff…

独立看门狗与窗口看门狗

定义 看门狗的本质是一个定时器&#xff0c;在启动后&#xff0c;需要在一定时间内再给它一个信号&#xff0c;俗称“喂狗”&#xff0c;如果没有按时“喂狗”&#xff0c;说明MCU可能处于非正常状态&#xff0c;这时看门狗就向MCU发送个复位信号&#xff0c;使整个系统重启&a…

51单片机数码管显示

文章目录前言一、数码管简介二、数码管原理图三、数码管显示原理四、静态数码管代表编写五、动态数码管总结前言 这篇文章将介绍数码管的显示其中包含了动态数码管和静态数码管两种。 一、数码管简介 数码管其实就是由多个发光二极管封装在一起组成“8”字型的器件当分别点亮…