嵌入式Linux系统编程 — 2.2 标准I/O库:检查或复位状态

news2024/11/23 13:33:16

目录

1 检查或复位状态简介

2 feof()函数

2.1 feof()函数简介

2.2 示例程序

3 ferror()函数

4 clearerr()函数

4.1 clearerr()函数简介

4.2 示例程序


1 检查或复位状态简介

调用 fread() 函数读取数据时,如果返回值小于参数 nmemb 所指定的值,这通常意味着发生了两种情况之一:要么是读取过程中遇到了文件末尾(end-of-file,EOF),要么是发生了某种错误。然而,fread() 函数本身并不提供足够的信息来区分这两种情况。有几种方法确定具体的原因:

  • 一种方法是检查错误标志,这可以通过调用 ferror() 函数实现,它会返回一个非零值如果文件流遇到了错误。
  • 另一种方法是检查文件结束标志,这可以通过调用 feof() 函数来完成,它会在到达文件末尾时返回一个非零值。

通过结合使用 ferror()feof() 函数,可以更准确地判断 fread() 返回较小值的具体原因,从而采取相应的处理措施。

2 feof()函数

2.1 feof()函数简介

feof() 函数是 C 语言标准库中的一个函数,用于检查文件流是否已到达文件末尾(end-of-file,EOF)。当从文件中读取数据时,如果已经读取到文件的最后,feof() 函数可以用来确定是否还有更多的数据可以读取。函数原型如下:

int feof(FILE *stream);
  • 参数: stream 是指向 FILE 结构的指针,该结构代表了要检查的文件流。
  • 函数返回值:如果文件流已经到达文件末尾,返回非零值(通常是 1),如果文件流还没有到达文件末尾,返回 0。

2.2 示例程序

下面的代码实现了检测文件的读写位置是否移动到了文件末尾,并逐个字符打印。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() 
{
    FILE *readFile, *writeFile;
    char buffer[256];
    const char *filename = "example.txt"; // 临时文件名

    // 打开文件以写入
    writeFile = fopen(filename, "w"); // 以文本写入模式打开文件
    if (writeFile == NULL) {
        perror("Error opening file for writing");
        return EXIT_FAILURE;
    }

    // 提示用户输入文本
    printf("Enter your text (max 1024 characters): ");
    fgets(buffer, sizeof(buffer), stdin); // 从标准输入读取一行文本
    // 写入文本到文件
    fputs(buffer, writeFile);

    // 关闭写入文件
    fclose(writeFile);

    // 打开同一个文件以读取
    readFile = fopen(filename, "r"); // 以文本读取模式打开文件
    if (readFile == NULL) {
        perror("Error opening file for reading");
        return EXIT_FAILURE;
    }

    // 循环读取文件,直到到达文件末尾
    while (!feof(readFile)) {
        int ch = fgetc(readFile); // 逐个字符读取
        if (ch != EOF) {
            printf("%c\n", ch); // 打印读取的字符
        } else {
            break; // 如果到达文件末尾或读取失败,退出循环
        }
    }

    // 检查是否有错误发生
    if (ferror(readFile) != 0) {
        perror("Error reading file");
    }

    // 关闭读取文件
    fclose(readFile);

    return EXIT_SUCCESS;
}

首先以文本写入模式打开(或创建)一个名为 "example.txt" 的文件,并将用户输入的文本存储到该文件中。接着,程序使用 feof() 函数检测是否到达文件末尾,并使用 fgetc() 函数逐个字符地读取文件内容,每个字符后跟一个换行符打印到标准输出。最后通过ferror() 函数来检查错误状态并关闭读取的文件。程序运行的结果如下:

 

3 ferror()函数

上面的示例程序中提到了库函数 ferror(),ferror()函数用于测试参数 stream 所指文件的错误标志,如果错误标志被设置了,则调用 ferror()函数将返回一个非零值,如果错误标志没有被设置,则返回 0。其函数原型如下所示:

#include <stdio.h>

int ferror(FILE *stream);

4 clearerr()函数

4.1 clearerr()函数简介

库函数 clearerr()用于清除 end-of-file 标志和错误标志,当调用 feof()或 ferror()校验这些标志后,通常需要清除这些标志,避免下次校验时使用到的是上一次设置的值,此时可以手动调用 clearerr()函数清除标志。函数原型如下:

void clearerr(FILE *stream);

使用场景:当你检测到文件流有错误(通过 ferror(stream))或到达文件末尾(通过 feof(stream))后,如果还想继续从该流中读取或写入数据,你可以使用 clearerr() 来清除这些标志。这通常在你解决或忽略了错误,并希望继续处理文件时使用。

4.2 示例程序

下面的代码实现了利用clearerr()函数清除文件流 fileStream 的 EOF 标志和错误标志。

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    FILE *fileStream = NULL;  // 更具描述性的变量名
    const char *filename = "example.txt"; // 临时文件名
    char buffer[20] = {0};   // 使用 buffer 替代 buf,更清晰地表达用途

    /* 打开文件 */
    if (NULL == (fileStream = fopen(filename, "w"))) {
        perror("Error opening file");
        exit(EXIT_FAILURE);  // 使用 EXIT_FAILURE 宏替代 -1
    }
    printf("File opened successfully!\n");

    /* 移动读写位置到文件末尾 */
    if (0 > fseek(fileStream, 0, SEEK_END)) {
        perror("Error seeking to end of file");
        fclose(fileStream);
        exit(EXIT_FAILURE);
    }

    /* 读取文件 */
    if (fread(buffer, 1, 10, fileStream) < 10) {  // 检查是否成功读取 10 个字符
        if (feof(fileStream)) {
            printf("End-of-file flag is set, reached the end of file!\n");
        } else {
            perror("Error reading file");
        }
        clearerr(fileStream);  // 清除 EOF 或错误标志
    }

    /* 关闭文件 */
    fclose(fileStream);
    exit(EXIT_SUCCESS);  // 使用 EXIT_SUCCESS 宏替代 0
}

首先尝试以写入模式打开一个文件,然后将文件指针移动到文件末尾。接着读取文件,如果读取的字节少于预期,它将检查是否到达文件末尾或发生错误。clearerr(fileStream); 这行代码用于清除文件流 fileStream 的 EOF 标志和错误标志,使得后续操作可以继续在文件流上进行,而不受之前错误或 EOF 状态的影响。最后,代码关闭文件并正常退出。运行的结果如下:

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

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

相关文章

python常见数据分析函数

apply DataFrame.apply(func, axis0, broadcastFalse, rawFalse, reduceNone, args(), **kwds) 第一个参数是函数 可以在Series或DataFrame上执行一个函数 支持对行、列或单个值进行处理 import numpy as np import pandas as pdf lambda x: x.max()-x.min()df pd.DataFrame(…

【数据结构】详解堆的基本结构及其实现

文章目录 前言1.堆的相关概念1.1堆的概念1.2堆的分类1.2.1小根堆1.2.2大根堆 1.3堆的特点堆的实用场景 2.堆的实现2.1初始化2.2插入2.3堆的向上调整2.4删除2.5堆的向下调整2.6判空2.7获取堆顶元素2.8销毁 3.堆排序3.1实现3.2堆排序的时间复杂度问题 前言 在上一篇文章中&#…

【数据库】SQL零基础入门学习

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

如何通过 4 种方式备份和恢复Android联系人

毫无疑问&#xff0c;联系人是Android手机上存储的最重要的信息之一。为了保护这些重要数据&#xff0c;明智的做法是对Android手机进行联系人备份。如果您的手机发生任何情况导致数据丢失&#xff0c;例如被盗、系统崩溃或物理损坏&#xff0c;您可以再次将备份中的联系人恢复…

Typecho:简约而强大的开源PHP博客平台

Typecho&#xff1a;让博客写作回归本质- 精选真开源&#xff0c;释放新价值。 概览 Typecho是一个开源的PHP博客平台&#xff0c;以其简洁的界面和强大的功能&#xff0c;为博客作者提供了一个高效、易于管理的写作环境。它是一个轻量级、高性能的解决方案&#xff0c;适用于…

主流数据库的大数据插入对比(mssql[sql server]、oracle、postgresql、mysql、sqlite)

首先申明&#xff0c;做这个对比不代表数据库性能&#xff0c;纯属好奇。勿喷&#xff0c;感谢。 测试连续11次插入数据库&#xff0c;每次100万行数据。 测试环境&#xff1a;单机测试&#xff0c;就是所有数据库都装在本机上。操作系统:windows server 2016&#xff0c;使用…

【YOLOV8】1.开发环境搭建

Yolo8出来一段时间了,包含了目标检测、实例分割、人体姿态预测、旋转目标检测、图像分类等功能,所以想花点时间总结记录一下这几个功能的使用方法和自定义数据集需要注意的一些问题,本篇是第一篇,开发环境的配置。 YOLO(You Only Look Once)是一种流行的物体检测和图像分割…

工控主板分类详解

1.ATX系列 尺寸305*244mm;接口扩展丰富,更多的内存和PCIE插槽; 进一步略小的有MATX,尺寸244*244cm;扩展插槽缩减,但兼容ATX接口,依旧是按照ATX标准 2.ITX系列 尺寸170*170mm;相较于ATX主板更加迷你,功能接口也少一些; 常用于小型计算机或者嵌入式系统 高能计算机推…

【Pycharm】功能介绍

1.Code Reformat Code 格式化代码&#xff0c;可以帮助我们去自动调整空格等&#xff0c;根据python语法规范自动调整 2.Settings 1.创建py文件默认填充模版 3.读写py文件编码格式一致性 顶部代码指定的编码方式作用&#xff1a; 可以保证python2/3解释器在读取文件的时候按…

将HTML页面中的table表格元素转换为矩形,计算出每个单元格的宽高以及左上角坐标点,输出为json数据

export function huoQuTableElement() {const tableData []; // 存储表格数据的数组let res [];// 获取到包含表格的foreignObject元素const foreignObject document.getElementById(mydctable);if (!foreignObject){return ;}// 获取到表格元素let oldTable foreignObject…

python tk实现标签切换页面

import tkinter as tk from tkinter import ttk# 初始化主窗口 root tk.Tk() root.title("标签页示例")# 设置窗口大小 root.geometry("400x300")# 创建 Notebook 小部件 notebook ttk.Notebook(root) notebook.pack(expandTrue, fill"both")#…

【leetcode面试经典150题】-45. 跳跃游戏 II

【leetcode面试经典150题】-45. 跳跃游戏 II 1 题目介绍2 个人解题思路2.1 代码 3 官方题解3.1 代码 1 题目介绍 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] …

[职场] 研究生面试自我介绍_1 #经验分享#知识分享

研究生面试自我介绍 想要进入职场&#xff0c;面试是必不可少的。然而想要面试成功&#xff0c;就需要一个让人印象深刻的自我介绍&#xff0c;好的自我介绍可以让面试官&#xff0c;快速了解自己&#xff0c;快速记住自己。 一、范文1 我是一名硕士研究生&#xff0c;即将毕业…

如何查询公网IP?

在互联网中&#xff0c;每个设备都有一个唯一的公网IP地址&#xff0c;用于标识设备在全球范围内的位置。查询公网IP是一个常见的需求&#xff0c;无论是用于远程访问、网络配置还是其他目的&#xff0c;了解自己的公网IP地址都是很有必要的。本文将介绍几种常见的方法来查询公…

【ArcGISProSDK】 读取多面体信息并导出XML

结果展示 代码 using ArcGIS.Core.CIM; using ArcGIS.Core.Data; using ArcGIS.Core.Data.DDL; using ArcGIS.Core.Geometry; using ArcGIS.Core.Internal.CIM; using ArcGIS.Desktop.Catalog; using ArcGIS.Desktop.Core; using ArcGIS.Desktop.Editing; using ArcGIS.Deskto…

DSP问题:CCS更改工程名导入报错

1、问题现象 复制一个工程出来后&#xff0c;修改版本号&#xff0c;重新导入工程后报错。 显示项目描述无效。 2、问题原因 由于CCS无法通过工程描述中找到指定名字文件夹。使用记事本打开.project文件&#xff0c;里面的描述还是以前的文件夹名&#xff0c;所以导入时报…

达梦8 网络中断对系统的影响

测试环境&#xff1a;三节点实时主从 版本&#xff1a;--03134283938-20221019-172201-20018 测试1 系统没有启动确认监视器 关闭节点3网卡 登录节点1检查主库状态 显示向节点2发送归档成功&#xff0c;但无法收到节点3的消息&#xff0c;节点1挂起 日志报错如下&#xf…

《系统架构设计师教程(第2版)》第11章-未来信息综合技术-02-人工智能技术概述

文章目录 1. 人工智能&#xff08;AI&#xff09;1.1 弱人工智能1.2 强人工智能 2. 人工智能的发展历程3. 人工智能关键技术31. 自然语言处理 (Natural Language Processing)3.2 计算机视觉 (Computer Vision)3.3 知识图谱 (Knowledge Graph)3.4 人机交互 (Human-Computer Inte…

Linux - 深入理解/proc虚拟文件系统:从基础到高级

文章目录 Linux /proc虚拟文件系统/proc/self使用 /proc/self 的优势/proc/self 的使用案例案例1&#xff1a;获取当前进程的状态信息案例2&#xff1a;获取当前进程的命令行参数案例3&#xff1a;获取当前进程的内存映射案例4&#xff1a;获取当前进程的文件描述符 /proc中进程…

二叉树的先序创建、复制、深度及结点个数

文章目录 前言一、二叉树的先序创建二、二叉树的复制三、二叉树的深度四、二叉树的结点个数总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#xff0c;便于日后复习&#xff08;这种事情不要啊&#xff09;。所用教材为《数据结构 C语言版…