【嵌入式高级C语言】10:C语言文件

文章目录

  • 1 文件的概述
    • 1.1 文件分类(存储介质)
    • 1.2 磁盘文件分类(存储方式)
    • 1.3 二进制文件和文本文件的区别
  • 2 文件缓冲区
  • 3 文件指针
  • 4 文件的API
    • 4.1 打开文件
    • 4.2 关闭文件
    • 4.3 重新定位流
      • 4.3.1 fseek
      • 4.3.2 ftell
      • 4.3.3 rewind
    • 4.4 字符输出到文件
    • 4.5 字符串输出到文件
    • 4.6 字符的输入
    • 4.7 字符串的输入
    • 4.8 二进制流输出
    • 4.9 二进制流输入
  • 5 示例

1 文件的概述

1.1 文件分类(存储介质)

image.png

1.2 磁盘文件分类(存储方式)

  1. 从物理的角度看

任何磁盘文件在物理上都是二进制存储的。


  1. 从逻辑的角度看


1.3 二进制文件和文本文件的区别

image.png
image.png

2 文件缓冲区

image.png

文件缓冲区的作用:提高访问效率,提高磁盘使用寿命。

Linux下缓冲区的4种刷新方式

  1. 行刷新(遇到换行符刷新)。
  2. 满刷新(缓冲区数据放满刷新)。
  3. 强制刷新(使用fflush函数将缓冲区刷新)。
  4. 关闭刷新(关闭文件时将缓冲区数据全部刷新)。

fflush()详解

fflush - 刷新流
对于输出流,fflush()通过流的底层写入函数,强制写入所有的用户空间缓存数据到给定的输出或者更新流。
如果流的参数为NULLfflush()会刷新所有打开的输出流。

概要
	#include <stdio.h>
	
	int fflush(FILE *stream);

参数
	stream - 流

返回值
	成功完成后返回 0。否则,返回 EOF 并返回 errno设置以指示错误。

示例:制作模拟时钟

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int min = 0;
    int sec = 0;

    while (1)
    {
        // 输出时钟
        printf("\r%02d:%02d", min, sec);

        // 刷新缓冲区
        fflush(stdout);

        // 睡眠1秒
        sleep(1);

        // 时钟逻辑判断
        sec++;
        if (60 == sec)
        {
            sec = 0;
            min++;
            if (60 == min)
            {
                min = 0;
            } /* end of if (60 == min) */

        } /* end of if (60 == sec) */

    } /* end of while (1) */


    return 0;
}

3 文件指针

所有操作文件的库函数都需要借助文件指针操作文件。

  1. 定义文件指针的一般形式为FILE *指针变量标识符,FILE为大写,需包含<stdio.h>
  2. FILE是系统使用typedef定义出来的有关文件信息的一种结构体变量,含有文件名、文件状态和文件当前位置等信息。
  3. 一般情况下,我们操作文件前必须定义一个文件指针来标示我们将要操作的文件。
  4. 在实际编程中,我们无需关心FILE结构体的细节,只需要将文件指针传给io库函数,库函数再通过结构体里的信息对文件进行操作。

对文件操作的步骤

  1. 对文件进行读写等操作之前要打开文件得到文件指针。
  2. 可以通过文件指针对文件进行读写操作。
  3. 读写等操作完毕后,需要关闭文件,关闭文件后,就不能再通过此文件指针操作文件了。

补充:在C语言中有三个特殊的文件指针无需定义,在程序中可以直接使用(每个进程)

  • stdin:标准输入。–> 默认为当前终端(键盘)
  • stdout:标准输出。–> 默认为当前终端(屏幕)
  • stderr:标准错误输出设备。–> 默认为当前终端(屏幕)

4 文件的API

4.1 打开文件

fopen - 流打开函数
fopen() 函数打开名称为路径名指向的字符串的文件并将流与其关联。

概要
	#include <stdio.h>
	
	FILE *fopen(const char *pathname, const char *mode);

参数
	pathname - 文件路径名
	mode - 文件打开模式
		r    打开文本文件进行读取。该流位于文件开头。
		r+   打开以进行读取和写入。该流位于文件开头。
		w    将文件截断为零长度或创建用于写入的文本文件。流是位于文件的开头。
		w+   打开以进行读取和写入。如果文件不存在则创建,否则它会被截断。该流位于该流的文件开头。
		a    打开以追加(写入文件末尾)。如果不存在则创建该文件。该流位于文件末尾。
		a+   打开以进行读取和追加(写入文件末尾)。该文件不存在则创建。输出总是附加到末尾文件。

返回值
	成功完成后,fopen()fdopen()freopen() 返回一个 FILE 指针。
	否则,返回 NULL 并设置 errno 来指示错误。

image.png

4.2 关闭文件

fclose - 关闭流
fclose() 函数刷新流指向的流(写入任何缓冲的使用 fflush(3)) 输出数据并关闭底层文件描述符。

概要
	#include <stdio.h>
	
	int fclose(FILE *stream);

参数
	stream - 文件流

返回值
	成功完成后,返回 0。
	否则,返回 EOF 并返回 errno设置以指示错误。

4.3 重新定位流

4.3.1 fseek

fseek - 重新定位流
fseek() 函数设置流指向的流的文件位置指示符。新位置(以字节为单位)是通过将偏移字节添加到由whence指定的位置。
如果whence设置为SEEK_SETSEEK_CURSEEK_END,偏移量相对于文件的开头,指示符当前位置或文件结尾。

概要
	#include <stdio.h>
	
	int fseek(FILE *stream, long offset, int whence);

参数
	stream - 文件流
	offset - 偏移量
	whence - 流指针位置
		SEEK_SET - 文件的开头
		SEEK_CUR - 指示符当前位置
		SEEK_END - 文件结尾
		
返回值
	成功完成后,返回0。
	否则,-1返回并设置 errno 以指示错误。

4.3.2 ftell

ftell - 重新定位流
ftell() 函数获取stream 指向的流的文件位置指示符的当前值。

概要
	#include <stdio.h>
	
	long ftell(FILE *stream);

参数
	stream - 文件流

返回值
	成功完成后ftell() 返回当前偏移量。
	否则,-1返回并设置 errno 以指示错误。

4.3.3 rewind

rewind - 重新定位流
rewind() 函数设置指向的流的文件位置指示器流到文件的开头。
相当于 fseek(stream, 0L, SEEK_SET);

概要
	#include <stdio.h>
	
	void rewind(FILE *stream);

参数
	stream - 文件流

返回值
	rewind() 函数不返回任何值。

4.4 字符输出到文件

fputc - 字符输出到文件
fputc() 将字符 c 写入流,转换为无符号字符。

概要
	#include <stdio.h>
	
	int fputc(int c, FILE *stream);

参数
	c - 字符
	stream - 文件流

返回值
	返回以 unsigned char 形式写入的字符;
	出错时转换为 intEOF

4.5 字符串输出到文件

fputs - 字符串输出到文件
fputs() 将字符串 s 写入流,不带终止空字节 ('\0')。

概要
	#include <stdio.h>
	
	int fputs(const char *s, FILE *stream);

参数
	s - 字符串首地址
	stream - 文件流

返回值
	成功时返回一个非负数,在错误时返回 EOF

4.6 字符的输入

fgetc - 字符的输入
fgetc() 从流中读取下一个字符并将其作为无符号字符返回;
在文件末尾或发生错误时转换为 intEOF。

概要
	#include <stdio.h>
	
	int fgetc(FILE *stream);

参数
	stream - 文件流

返回值
	返回作为 unsigned char 转换读取的字符;
	文件末尾或错误时为 intEOF

4.7 字符串的输入

fgets - 字符串的输入
fgets() 从流中最多读取一个小于 size 的字符并将它们存储到s指向的缓冲区中。
读取在 EOF 或换行符后停止。如果读取换行符,则将其存储到缓冲区中。一个术语空字节('\0')存储在缓冲区中最后一个字符之后。

概要
	#include <stdio.h>
	char *fgets(char *s, int size, FILE *stream);

参数
	s - 缓冲区地址
	size - 缓冲区总大小
	stream - 流

返回值
	fgets() 成功时返回 s,出错时或在未读取字符的情况下发生文件末尾时返回 NULL。

注意
	不建议将对 stdio 库的输入函数的调用与对 read(2) 的低级调用混合使用与输入流关联的文件描述符;结果将是不确定的,很可能不是你要。

4.8 二进制流输出

fwrite - 二进制流输出
函数 fwrite() 将 nmemb 数据项(每个大小size)写入Stream 指向的流,从 ptr 给出的位置获取它们。

概要
	#include <stdio.h>
	
	size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

参数
	ptr - 写入数据的地址
	size - 块大小
	nmemb - 块数
	stream - 文件流

返回值
	成功后,fwrite() 返回写入的项目数。这仅当 size 为 1 时,number 才等于传输的字节数。

4.9 二进制流输入

fread - 二进制流输入
函数 fread() 从以下位置读取 nmemb 数据项,每个大小为 size 长 Stream 指向的流,将它们存储在 ptr 指定的位置。

概要
	#include <stdio.h>
	
	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

参数
	ptr - 存储数据的地址
	size - 块大小
	nmemb - 块数
	stream - 文件流

返回值
	成功后,fread() 返回读取的项目数。这仅当 size 为 1 时,number 才等于传输的字节数。

注意
	fread() 不区分文件结束和错误,调用者必须使用feof(3)ferror(3) 来确定发生了哪一个。

5 示例

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE *fp = NULL;
    char str[128] = "hello world!";
    long ret = 0L;

    /* 打开文件 */
    fp = fopen("test", "w+");
    if (NULL == fp)
    {
        perror("fopen");
        return -1;
    } /* end of if (NULL == fp) */

    /* 写入 */
    ret = fwrite(str, sizeof(char), sizeof(str), fp);

    printf("%ld\n", ret);

    /* 关闭文件 */
    fclose(fp);
    fp = NULL;

    return 0;
}
$ ./a.out 
128

image.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的快递配送规划系统的设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术 3 1.1 Spring Boot框架 3 1.2 Vue框架 4 1.4 Bootstrap框架 4 1.5 JQuery技术 5 1.6 Ajax技术 5 1.7 ECharts 5 1.8 MySQL 6 1.9本章小结 6 2 系统分析 7 2.1 需求分析 7 2.2 非功能需求 10 2.3 本章小结 10 3 系统设计 11 3.1 …

如何发布新华网稿件,新华网报价多少钱?

在当今信息爆炸的时代&#xff0c;媒体的重要性不言而喻。而作为国内最具影响力的媒体之一&#xff0c;新华网更是备受关注。那么&#xff0c;作为一名公关从业者或者自媒体人士&#xff0c;如何能够在媒介多多网成功发布新华网的稿件呢&#xff1f;接下来&#xff0c;我们就来…

基于PSO粒子群算法的三角形采集堆轨道优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 假设一个收集轨道&#xff0c;上面有5个采集堆&#xff0c;这5个采集堆分别被看作一个4*20的矩阵&#xff08;下面只有4*10&#xff09;&#xff0c;每个模块&…

C语言学习--练习3(贪心)

目录 贪心算法 1. 两数对之间的最大乘积差 2.三角形的最大周长 3.数组拆分 4.救生艇 5.发送饼干 6.摆动数组 贪心算法 概念定义 所谓贪心&#xff0c;总是做出在当前看来是最好的选择。也就是说&#xff0c;不从整体最优上进行考虑&#xff0c;算法得到的是在某种…

300分钟吃透分布式缓存-26讲:如何大幅成倍提升Redis处理性能?

主线程 Redis 自问世以来&#xff0c;广受好评&#xff0c;应用广泛。但相比&#xff0c; Memcached 单实例压测 TPS 可以高达百万&#xff0c;线上可以稳定跑 20~40 万而言&#xff0c;Redis 的单实例压测 TPS 不过 10~12 万&#xff0c;线上一般最高也就 2~4 万&#xff0c;…

Microsoft Copilot 好像能把论文配图看明白了

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Microsoft Copilot 好像能把论文配图看明白了&#xff0c;下面是两个案例。 请用学术风格详细描述您的研究论文中的这幅配图。在描述时&#xff0c;请尽可能准确地阐述图片的主要元素、颜色、形状、大…

如何在一个pycharm项目中创建jupyter notebook文件,并切换到conda环境中

1、第一步可以直接在pycharm项目中创建jupyter notebook文件 2、假若想要切换成pytorch环境做实验例子&#xff0c;会发现报这个错误 Jupyter server process exited with code 1 C:\Users\12430\.conda\envs\pytorch3.11\python.exe: No module named jupyter在这里&#xff…

推理判断-聂佳-判读4-定义判断

知识点讲解 考点1 快速识别有效信息 考点2 同构选项排除 题目 考点1 快速识别有效信息 考点2 同构选项排除 总结

linuxOPS基础_操作系统概述

计算机发展史 第一台计算机是1946 年2 月14 日诞生日&#xff0c;第一台名称ENIAC。体积一间屋子的大小&#xff0c;重量高达28t。 第一代&#xff1a;1946 – 1958 > 12 年 &#xff08;电子管&#xff09; 第二代&#xff1a;1958 – 1964 > 6 年 &#xff08;晶体管…

kafka(三)springboot集成kafka(1)介绍

基于kafka新版本 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.0.0</version></dependency> </dependencies> 一、kafkaProducer 1、介绍…

HTML 学习笔记(九)颜色值和长度单位

一、颜色 1.通过RGB值来设置颜色 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>table</title&…

【Linux】线程同步与生产消费者问题

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;CP问题&#x1f449;&#x1f3fb;互斥…

c语言,大宗撮合交易中心系统核心模块代码

撮合交易系统&#xff08;Matching System&#xff09;常用于大宗交易&#xff0c;如股票、期货等市场&#xff0c;它负责根据买卖双方的报价和数量&#xff0c;自动撮合成交。撮合系统的核心模块通常包括订单管理、价格计算和撮合逻辑等部分。 由于撮合系统的实现复杂且依赖于…

【C++ 学习】拷贝构造你了解多少?

文章目录 1. 拷贝构造的引入2. 拷贝构造的引用场景 1. 拷贝构造的引入 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&#xff0c;在用已存在的类类型对象创建新对象时由编译器自动调用&#xff1b; 特征&#xff1a; ① …

集合实现类研究底层(部分):手撕ArrayList底层源码、手撕LinkedList底层源码、手写单向链表和双向链表

day26上 集合框架图 标绿已经学习底层&#xff0c;深入底层主要是研究实现类底层 继承关系图 手撕ArrayList底层源码 ps:研究添加元素的过程 思路&#xff1a; 1.研究继承关系 2.研究属性 3.理解创建集合的过程 – 构造方法的底层原理 4.研究添加元素的过程 提升&#xff1a…

变换,动画

面试题——需求&#xff1a;在不知道父元素与子元素的宽高时 如何让子元素在父元素内居中&#xff1f; 1.定位 父相子绝 2.子元素 top&#xff1a;50% left:50% 3.子元素 transform: translate(-50%,-50%) .parent{height: 500px;background-color: red;position: relative;}.c…

算法第二十五天-寻找排序数组中的最小值

寻找排序数组中的最小值 题目要求 解题思路 二分法 代码 class Solution:def findMin(self, nums: List[int]) -> int:low, high 0, len(nums) - 1while low < high:pivot low (high - low) // 2if nums[pivot] < nums[high]:high pivot else:low pivot 1re…

微信小程序-可以用区域

简介 movable-view和movable-area是可移动的视图容器&#xff0c;在页面中可以拖拽滑动。 本篇文章将会通过该容器实现一个常用的拖拽按钮功能。 使用效果 代码实现 side-view.wtml 布局见下面代码&#xff0c;left view为内容区域&#xff0c;right view为操作按钮&a…

进腾讯工作一个月,我想辞职了......

前几天&#xff0c;我在网上看到一个微博。 一个应届的校招生&#xff0c;目前入职腾讯&#xff0c;工作了一个月。这一个月给他的感受是大量的写测试用例&#xff0c;自己写测试用例的能力熟练了不少&#xff0c;测试技能倒是没有多大的提高&#xff0c;真正需要技术的工作却…

算法学习01:排序二分

算法学习01&#xff1a;排序&&二分 文章目录 算法学习01&#xff1a;排序&&二分前言需要记忆的模版&#xff1a;快速排序归并排序&#xff1a;整数二分&#xff1a;浮点数二分 一、排序1.快速排序2.归并排序&#xff1a; 二、二分1.整数2.浮点数 总结 前言 需要…