标准IO总结

目录

标准IO总结

[一、fopen 打开文件](#一、fopen 打开文件)

[二、fread、fwrite 读写文件](#二、fread、fwrite 读写文件)

[三、fclose 关闭文件](#三、fclose 关闭文件)

[四、fseek 设置读写位置偏移量函数](#四、fseek 设置读写位置偏移量函数)

[五、ftell 获取文件当前读写位置偏移量](#五、ftell 获取文件当前读写位置偏移量)

[六、feof 测试end-of-file标志函数](#六、feof 测试end-of-file标志函数)

[七、ferror 测试文件错误标志](#七、ferror 测试文件错误标志)

[八、clearerr 清除end-of-file标志和错误标志](#八、clearerr 清除end-of-file标志和错误标志)

[九、printf、fprintf、dprintf、sprintf、snprintf 格式化输出](#九、printf、fprintf、dprintf、sprintf、snprintf 格式化输出)

[十、scanf、fscanf、sscanf 输入](#十、scanf、fscanf、sscanf 输入)

示例代码

十一、标准IO与文件IO的区别

[十二、 setvbuf、setbuf 、setbuffer 对stdio缓冲区的设置](#十二、 setvbuf、setbuf 、setbuffer 对stdio缓冲区的设置)

[十三、fflush 刷新缓冲区](#十三、fflush 刷新缓冲区)

[十四、fileno、fdopen 文件描述符与FILE指针互转](#十四、fileno、fdopen 文件描述符与FILE指针互转)


标准IO总结

对于之前我们编写的关于标准IO总结:https://blog.csdn.net/2403_82436914/article/details/147078393?spm=1001.2014.3001.5502 ,我们认为太过于臃肿,不够精简,为了方便您快速上手使用标准IO的API,并完成对于的需求代码编写,我们总结了如下的文档,来介绍标准IO的API的使用。希望对您的开发和学习有帮助。

一、fopen 打开文件

cpp 复制代码
#include <stdio.h>
​
FILE *fopen(const char *path, const char *mode);

path:文件的绝对路径或相对路径。

mode :指定文件的读写权限,以字符串方式呈现如:r只读方式打开。r+可读可写打开。w只写方式打开,如果文件存在打开时将里面内容清空,如果不存在则创建该文件。 w+以可读写方式打开文件,如果文件存在则清空文件,如果文件不存在则创建该文件。a只写方式打开文件,而且是以追加内容方式打开,如果文件不存在则创建该文件。a+可读可写方式打开文件,而且是以追加的方式打开,如果不存在则创建该文件。

返回值:成功返回一个指向FILE类型的指针(TIps:FILE是一个结构体类型,包含文件的描述符、指向文件缓冲区的指针、缓冲区的长度、当前缓冲区中的字节数以及出错标志等),该指针与打开或创建的文件相关联。失败时返回NULL。

二、fread、fwrite 读写文件

cpp 复制代码
#include <stdio.h>
​
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

ptr:要读出或写入的数据。

size:表示数据项nmemb的大小(字节为单位)。

nmemb:要读出或写入的数据项的个数。

(Tips:意思我们实际读出或写入的数据大小为size * nmemb(单位为字节))

stream:FILE指针。

返回值:成功时返回读出或写入的数据项的个数(Tips:注意返回的不是实际读出或写入的字节数,而是实际写入的数据项个数)。失败返回的值小于参数nmemb或者等于0。

三、fclose 关闭文件

cpp 复制代码
#include <stdio.h>
​
int fclose(FILE *stream);

stream:FILE指针。

返回值:成功返回0,失败返回EOF。

四、fseek 设置读写位置偏移量函数

cpp 复制代码
#include <stdio.h>
​
int fseek(FILE *stream, long offset, int whence);

stream:FILE指针。

offset:偏移量,表示从指定的基准位置(whence)移动的字节数,正数向后移,负数向前移。

whence:基准位置,常见的值包括:

  • SEEK_SET:从文件开头开始偏移。

  • SEEK_CUR:从文件当前偏移量开始偏移。

  • SEEK_END:从文件末尾开始偏移。

返回值:成功返回0。失败返回-1。

五、ftell 获取文件当前读写位置偏移量

cpp 复制代码
#include <stdio.h>
​
long ftell(FILE *stream);

stream:FILE指针。

返回值:成功返回当前位置偏移量(字节)。失败返回-1。

六、feof 测试end-of-file标志函数

(Tips:feof函数是用来查看end-of-file标志的,如果标志没有被设置返回0,如果标志被设置了返回非零值。这个一般用在fread读取数据返回值小于nmemb时,判断是到达文件末尾还是已经结束的测试方法)

cpp 复制代码
#include <stdio.h>
​
int feof(FILE *stream);

stream:FILE指针。

返回值:返回0表示文件读写位置没有到文件末尾,返回非零表示文件已经到达末尾。

七、ferror 测试文件错误标志

cpp 复制代码
#include <stdio.h>
​
int ferror(FILE *stream);

stream:FILE指针。

返回值:返回0表示文件没有发生错误,返回非零表示文件发生了错误。

八、clearerr 清除end-of-file标志和错误标志

cpp 复制代码
#include <stdio.h>
​
void clearerr(FILE *stream);

stream:FILE指针。

九、printf、fprintf、dprintf、sprintf、snprintf 格式化输出

(Tips:printf用于将格式化数据写入到标准输出stdout。fprintf和dprintf用于将格式化数据写入到指定的文件中。sprintf和snprintf用于将格式化数据写入到用户指定的缓冲区buf中)

cpp 复制代码
#include <stdio.h>
​
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int dprintf(int fd, const char *format, ...);
int sprintf(char *buf, const char *format, ...);
int snprintf(char *buf, size_t size, const char *format, ...);

format:格式控制字符串,指定后续参数如何进行格式转换

(Tips:格式控制字符串由普通字符(除%以外)和转换说明组成,每个转换说明都会依次的对应后续的一个参数下面图片是转换说明的格式

在学C语言的时候我们已经记过,如:%d、%f、%c、%s

stream:FILE指针。

fd:文件描述符。

buf:用户指定缓冲区

size:要写入的实际字节数

返回值:成功返回写入的字节数。失败返回负值。

十、scanf、fscanf、sscanf 输入

(Tips:scanf读取用户输入的数据进行格式化转换,fscanf从指定文件中读取数据并进行转换,sscanf从str字符串中读取数据进行转换)

cpp 复制代码
#include <stdio.h>
​
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

format:格式控制字符串,指定后续参数如何进行格式转换

stream:FILE指针。

str:用户指定的字符串缓冲区。

示例代码

需求:使用标准IO的API,实现对文件的创建打开、写、移动读写位置、读、关闭文件操作。

您可以参考下面的代码完成自己的需求编写

cpp 复制代码
/********************************************
 *项目所有的文件名:standard_io.c test.txt
 *作者:SELSL
 *版本:v1.0
 *描述: 使用标准IO的API,实现对文件的创建打开、写、移动读写位置、读、关闭文件操作。
 *其他:无
 *论坛:无
 *日志:初版 v1.0 2025/12/18  SELSL创建
 ********************************************/
​
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
​
#define pathName "test.txt"
​
int main(int argc, const char *argv[])
{
    //打开文件
    FILE *fp = NULL;
    fp = fopen(pathName, "a+");
    if(NULL == fp)
    {
        perror("打开文件错误");
        exit(-1);
    }
​
    //写入数据
    char *buf = "This is SELSL!\n";
    int ret = 0;
    ret = fwrite(buf, sizeof(char), strlen(buf) + 1, fp);
    if(ret < (strlen(buf) + 1))
    {
        printf("写入数据失败\n");
        fclose(fp);
        exit(-1);
    }
​
    //计算写入的字节数
    int count = 0;
    count = ftell(fp);
    if(-1 == count)
    {
        printf("获取文件读写位置偏移量失败\n");
    }
    printf("总共写入了文件的字节数为:%d\n写入的数据为:%s", count, buf);
​
    //移动到要读取的位置
    ret = fseek(fp, -8, SEEK_CUR);
    if(-1 == ret)
    {
        printf("设置读写位置偏移量失败\n");
        fclose(fp);
        exit(-1);
    }
​
    //读取数据
    char *buf2 = (char *)malloc(sizeof(char) * 5);
    ret = fread(buf2, sizeof(char), 5, fp);
    if(5 > ret)
    {
        //查看数据是否到末尾
        if(feof(fp))
        {
            printf("读取文件已经到文件末尾\n");
        }
        clearerr(fp);
        fclose(fp);
        exit(-1);
    }
    printf("从文件%s中读到的数据为%s\n", pathName, buf2);
​
    return 0;
}
复制代码

十一、标准IO与文件IO的区别

标准IO总体效率高于文件IO,标准IO本质是对文件IO的封装,标准IO将用户读取或写入的数据缓存在stdio缓冲区中,然后再一次性的将stdio缓冲区中的数据通过文件IO写入或读取到内核缓冲区,然后内核再通过算法来进行磁盘的读写。整体上标准IO引入stdio缓冲区,减少了系统调用的次数,所以效率是高于文件IO的。

十二、 setvbuf、setbuf 、setbuffer 对stdio缓冲区的设置

cpp 复制代码
#include <stdio.h>
​
//可设置缓冲区的缓冲模式、缓冲区的大小、起始地址
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
//这个函数调用相当于执行setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);其中BUFSIZ为8192)
void setbuf(FILE *stream, char *buf);
//这个函数相当于执行setvbuf(stream, buf, buf ? _IOFBF : _IONBF, size);
void setbuffer(FILE *stream, char *buf, size_t size);

stream:FILE指针

buf:该参数为NULL而且mode参数不为非缓冲模式时,stdio库会自动分配一块空间作为stdio的缓冲区。当然用户也可以自己以动态或静态方式malloc申请分配一块空间作为stdio缓冲区。

mode:有如下取值(Tips:系统默认是行缓冲)

  • _IONBF:无缓冲,直接进行文件IO

  • _IOLBF:行缓冲,遇到\n时才会执行文件IO

  • _IOFBF:全缓冲,在添满stdio缓冲区才会执行文件IO

size:缓冲区的大小

返回值:成功返回0。失败返回非零。

十三、fflush 刷新缓冲区

cpp 复制代码
#include <stdio.h>
​
//将stdio缓冲区数据刷新到内核缓冲区
int fflush(FILE *stream);

stream:FILE指针,如果为空表示刷新所有stdio缓冲区

返回值:成功返回0。失败返回-1。

(Tips:我们的文件关闭、程序退出也会将stdio缓冲区的数据自动刷新内核缓冲区,注意如果使用_exit_Exit退出的程序就不会自动刷新到内核缓冲区)

十四、fileno、fdopen 文件描述符与FILE指针互转

cpp 复制代码
#include <stdio.h>
​
//将FILE指针转换为文件描述符,失败返回-1
int fileno(FILE *stream);
//将文件描述符转换为FILE指针,失败返回NULL
FILE *fdopen(int fd, const char *mode);

stream:FILE指针

fd:文件描述符

mode :指定文件的读写权限,以字符串方式呈现如:r只读方式打开。r+可读可写打开。w只写方式打开,如果文件存在打开时将里面内容清空,如果不存在则创建该文件。 w+以可读写方式打开文件,如果文件存在则清空文件,如果文件不存在则创建该文件。a只写方式打开文件,而且是以追加内容方式打开,如果文件不存在则创建该文件。a+可读可写方式打开文件,而且是以追加的方式打开,如果不存在则创建该文件。

OK,到这里标准IO常用的函数已经梳理完了,文档参考了正点原子的《Linux C 应用编程手册》,主要以简洁的调用方式梳理了标准IO的调用,帮助您快速上手标准IO的API使用。

相关推荐
野生风长3 小时前
从零开始的C语言:文件操作与数据存储(上)(文件的分类,文件的打开和关闭)
c语言·开发语言
小柯博客3 小时前
从零开始打造 OpenSTLinux 6.6 Yocto 系统 - STM32MP2(基于STM32CubeMX)(九)
c语言·stm32·单片机·嵌入式硬件·物联网·嵌入式·yocto
大猫和小黄3 小时前
Ubuntu环境下GitBlit安装部署与版本库迁移
linux·运维·git·ubuntu·gitblit
良木生香3 小时前
【诗句结构-初阶】详解栈和队列(2)---队列
c语言·数据结构·算法·蓝桥杯
点亮一颗LED(从入门到放弃)3 小时前
设备树驱动(6)
linux
加勒比之杰克3 小时前
【操作系统原理】软硬链接与动静态库
linux·os·动静态库·软硬链接
量子炒饭大师3 小时前
Cyber骇客的LIFO深渊与FIFO管道 ——【初阶数据结构与算法】栈与队列
c语言·数据结构·c++·链表
KingRumn3 小时前
Linux进程间通信之消息队列(POSIX)实现篇
linux·服务器
Legendary_0083 小时前
Type-C一拖三快充线的核心优势与LDR6020方案深度解析
c语言·开发语言·电脑