标准IO函数

一、man手册

man手册是用于在linux系统中查询命令、函数等的帮助手册 ,不同的章节分类便于快速定位获取各类linux系统相关的帮助信息;

命令格式 查看内容 章节说明
man man man手册自身的章节说明 了解man手册整体架构和使用规范
man 1 要查看的内容 可执行程序或shell命令的帮助文档 "1"对应用户命令章节
man 2 要查看的内容 **系统调用(内核提供的函数)**相关帮助 "2"对应系统调用章节
man 3 要查看的内容 **库调用(库中的函数)**相关帮助 "3"对应库函数章节

二、打开关闭文件函数

2.1 fopen函数(打开函数)

项目 内容
所需头文件 #include <stdio.h>
原型 FILE *fopen(const char *pathname, const char *mode);
功能 用标准I/O的方式打开文件
pathname参数 文件路径和名字 ,不写路径默认打开当前路径下的文件
mode参数 打开文件的方式,见下方mode详细说明表
返回值 成功:返回FILE指针 失败:返回NULL,重置错误码

mode参数详细说明

mode 打开方式 文件不存在 文件存在 光标定位
r 只读 报错 正常打开 开头
r+ 读写 报错 正常打开 开头
w 只写 创建 清空 开头
w+ 读写 创建 清空 开头
a 追加 创建 不清空 结尾
a+ 读和追加 创建 不清空 读:开头 写:结尾

2.3 fclose函数(关闭函数)

项目 内容
所需头文件 #include <stdio.h>
原型 int fclose(FILE *stream);
功能 用标准I/O的方式关闭文件
stream参数 文件指针(由 fopen 返回的 FILE*)
返回值(成功) 返回 0
返回值(失败) 返回 EOF(即 -1),并重置错误码

fclose 在关闭文件之前,会自动将缓冲区中尚未写入文件的数据刷新(flush)到磁盘,然后再关闭文件。

三、错误信息函数

3.1 内核中错误码的问题

在Linux系统中,内核通过预定义宏(如 ENOENT)标识错误 ,错误码 errno (内核返回的) 为正整数,内核返回时(传递给应用层)用负数传递;错误码是int类型的数据

应用层看到的是返回值 -1 (表示失败),而真正的错误码仍然以正数 形式存在 errno 中。不是把错误码变成负数,而是用 -1 作为"失败"标志。

3.2 strerror函数(错误码转换为错误信息)

项目 内容
所需头文件 #include <string.h>
原型 char *strerror(int errnum);
功能 将错误码转换为错误信息
errnum参数 错误码(通常为 errno 的值)
返回值(成功) 返回指向错误信息的字符串指针
返回值(无效errnum) 返回结果由系统实现决定(通常返回通用错误描述,如 "Unknown error nnn")

3.3 perror函数(错误信息打印函数)

项目 内容
所需头文件 #include <stdio.h>
原型 void perror(const char *s);
功能 打印错误信息
参数 s 用户的附加信息(见下方详细说明)
返回值 无

perror 函数调用后会自动换行。

参数说明

条件 输出格式 示例(假设 errno = ENOENT)
s != NULL 且 *s != '\0' s: 错误消息(有空格) open failed: No such file or directory
s == NULL 或 *s == '\0' 不同系统可能输出: ① : 错误消息 ② 直接输出 错误消息 : No such file or directory 或 No such file or directory

四、字符读写函数

4.1 fgetc函数(读文件)

项目 内容
所需头文件 #include <stdio.h>
原型 int fgetc(FILE *stream);
功能 从文件流中读取当前位置的字符。每次调用会自动移动文件指针,指向下一个字符位置
stream参数 文件指针(由 fopen 返回的 FILE*)
返回值(成功) 返回无符号字符(unsigned char)的数值(范围 0~255),并转换为 int 返回
返回值 (失败/EOF) 返回 EOF(-1)

fgetc 返回的是 int 类型 ,而不是 char 类型。虽然它读取的是字符,但用 int 返回是有重要原因的。

它返回的是一个数字(ASCII码),但这个数字可以被直接当作字符来使用。

操作 数据流向 结果
fgetc(fp) 文件 → 临时内存(CPU寄存器) 数据在比较完后就销毁
ch = fgetc(fp) 文件 → 临时内存 → 变量 ch 数据永久保存在 ch 中

4.2 fputc函数(写入文件)

项目 内容
所需头文件 #include <stdio.h>
原型 int fputc(int c, FILE *stream);
功能 向文件中写入一个字符
参数 c 要写入的字符(以 int 形式传递,实际存储时会转换为 unsigned char)
参数 stream 文件指针(由 fopen 返回的 FILE*)
返回值(成功) 返回写入的字符的 ASCII 码 (unsigned char****转换为 int)
返回值(失败) 返回 EOF(-1)

五、字符串读写函数

5.1 fgets函数(读取)

项目 内容
所需头文件 #include <stdio.h>
原型 char *fgets(char *s, int size, FILE *stream);
功能 从文件流中读取字符串,最多读取 size - 1 个字符, 自动添加 \0 ;遇到换行符 \n 或 EOF 时停止 (换行符会被存储)
参数 s 用于存放读到的内容的内存首地址(缓冲区)
参数 size 想要读取的字节数(int类型) (实际最多读取 size - 1 个字符,留一个位置给 \0)
参数 stream 文件指针(由 fopen 返回的 FILE*)
返回值 (成功) 返回字符串 s(即指向缓冲区的指针)
返回值 (失败/EOF) 返回 NULL

5.2 fputs函数(写入)

项目 内容
所需头文件 #include <stdio.h>
原型 int fputs(const char *s, FILE *stream);
功能 将字符串 s 的内容写入到 stream 指向的文件中 ,仅写入字符串有效字符 (不包含末尾 \0)
参数 s 要写入字符串的首地址
参数 stream 文件指针(由 fopen 返回的 FILE*)
返回值 (成功) 返回非负整数(通常是 0 或写入的字符数,具体取决于实现)
返回值 (失败) 返回 EOF(-1)

六、二进制读写函数

直接操作原始的字节流,不对文本进行处理

6.1 fopen函数打开文件的方式

模式 文本模式 二进制模式 文件不存在 文件存在时行为 初始光标位置 读写能力
只读 r rb 报错 正常打开 开头 只读
读写 r+ r+b 报错 正常打开 开头 读写
只写 w wb 创建 清空内容 开头 只写
读写 w+ w+b 创建 清空内容 开头 读写
追加 a ab 创建 保留内容 末尾 只写(追加)
读+追加 a+ a+b 创建 保留内容 读:开头 / 写:末尾 读写(读从头,写从尾)

补充说明:

在 Linux 系统中,加 b 与否对文件操作行为没有实际影响(系统不区分文本/二进制模式)。

在 Windows 系统中,建议显式加上 b(如 rb、wb) ,避免因换行符转换(\n ↔ \r\n)导致数据损坏。

若代码需跨平台移植,显式加 b 是更稳妥的做法。

6.2 fread函数

项目 内容
头文件 #include <stdio.h>
函数原型 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能 从文件流中读取数据到内存缓冲区; 从stream中读取nmemb项数据 ,每项大小为size ,将它们存入ptr指向的位置中
参数 含义
ptr 存储读取数据的内存缓冲区首地址
size 每个数据项的大小 (单位:字节),建议设为 1,此时**nmemb 表示要读取的字节数**
nmemb 要读取的数据项的最大数量
stream 文件指针(已打开的文件流)
返回值 含义
== nmemb 成功读取全部请求的数据项
> 0 且 < nmemb 读取到部分数据,可能遇到文件末尾(EOF)或读取错误
== 0 没有读取到任何数据(文件尾或一开始就出错)

fread不区分文件结束(EOF)或者是读取错误 ,调用者必须使用feof函数或者ferror函数来区分场景

6.3 feof函数

项目 内容
头文件 #include <stdio.h>
函数原型 int feof(FILE *stream);
功能 判断是否读取到文件的结尾
参数 含义
stream 文件指针(已打开的文件流)
返回值 含义
非0值(真) 文件已到达末尾
0(假) 文件未到达末尾

feof 是 "被动检测" 结尾只有当读取操作(如 fread/fgetc)实际触发了文件末尾 时,标志位才会置为结束状态;文件结束标志只能通过clearerr 来清除

第二次使用feof的时候要用到clearerr 来清除文件结束标志;但想要用还需要用到文件指针函数;

clearerr 只是清除文件结束标志

直接用 feof 判断未读文件 ,返回的一定是 0(因为还没开始读,不存在 "已到结尾")

6.4 ferror函数

项目 内容
头文件 #include <stdio.h>
函数原型 int ferror(FILE *stream);
功能 检查由 stream 指定的文件流的错误标志
参数 含义
stream 文件指针(已打开的文件流)
返回值 含义
非0值(真) 文件流发生了错误
0(假) 文件流没有发生错误

额外说明:

ferror 只检测"是否发生过错误",不主动触发任何错误行为。

错误标志位一旦被置位(例如因读取失败、写入失败等),后续若不调用 clearerr(stream) 清除,ferror 会一直返回非 0,直到标志被手动清除。

通常与 feof 配合使用,在 fread 等函数返回值小于预期时,区分究竟是遇到文件末尾(用 feof 判断)还是发生错误(用 ferror 判断)

6.5 clearerr函数

项目 内容
头文件 #include <stdio.h>
函数原型 void clearerr(FILE *stream);
功能 清除指定文件流的文件结束标志和错误标志
参数 含义
stream 文件指针(已打开的文件流)
返回值 含义
无 -

额外说明:

当 feof 检测到文件结尾后,文件结束标志会被置位。如果想要重新读取 该文件(例如使用 rewind 或 fseek 回到开头),必须先调用 clearerr 清除结束标志,否则 feof 会持续返回非 0 值。

当 ferror 检测到错误后,错误标志会被置位。在修复问题 (如磁盘空间恢复、网络重连)后,必须先调用 clearerr 清除错误标志,才能让文件流恢复可用状态。

该函数通常与 rewind、fseek 等重新定位文件指针的函数配合使用。

6.6 fwrite函数

项目 内容
头文件 #include <stdio.h>
函数原型 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能 将内存中的数据写入文件流 将ptr指向的内存数据,按size字节为1项、共nmemb项,写入stream文件流
参数 含义
ptr 指向要写入数据的内存缓冲区首地址
size 每个数据项的大小(单位:字节),建议设为 1,此时 nmemb 表示要写入的字节数
nmemb 要写入的数据项的最大数量
stream 文件指针(已打开的文件流)
返回值 含义
== nmemb 成功写入全部请求的数据项
> 0 且 < nmemb 只写入了部分数据,可能遇到写入错误或文件末尾(如磁盘满)
== 0 没有写入任何数据

七、格式化输出函数

7.1 sprintf函数

项目 内容
头文件 #include <stdio.h>
函数原型 int sprintf(char *str, const char *format, ...);
功能 将格式化数据写入字符串(内存),不会输出到终端
参数 含义
str 目标内存地址(字符串缓冲区)
format 格式化字符串,定义输出的格式
... 可变参数列表,对应 format 中的占位符
返回值 含义
成功 返回格式化后的字符个数(不包括结尾的 '\0')
失败 返回一个负数(通常是 -1)
注意事项 说明
缓冲区溢出 sprintf 不检查目标缓冲区大小,可能导致溢出,建议改用 snprintf
自动添加结尾符 函数自动在 str 末尾添加 '\0',但返回的字符个数不包含它
典型用法 char buf[100]; int len = sprintf(buf, "num=%d", 123);

7.2 snprintf函数

项目 内容
头文件 #include <stdio.h>
函数原型 int snprintf(char *str, size_t size, const char *format, ...);
功能 将格式化数据写入字符串(内存),不会输出到终端,可限制写入长度
参数 含义
str 目标内存地址(字符串缓冲区)
size 缓冲区大小(单位:字节),最多写入 size 个字符,其中包括结尾的 '\0'
format 格式化字符串,定义输出的格式
... 可变参数列表,对应 format 中的占位符
返回值 含义
成功 返回格式化后的完整字符个数 (不包括结尾的 '\0'),即使该长度超过 size
失败 返回一个负数(通常是 -1)
注意事项 说明
缓冲区安全 snprintf 会保证 str 以 '\0' 结尾(当 size > 0 时),不会溢出
截断检测 若返回值 >= size,说明输出被截断,完整字符串长度超出缓冲区限制
典型用法 char buf[50]; int len = snprintf(buf, sizeof(buf), "num=%d", 123);
与 sprintf 的区别 sprintf 不安全(无长度限制),snprintf 更安全,推荐使用

7.3 fprintf函数

项目 内容
头文件 #include <stdio.h>
函数原型 int fprintf(FILE *stream, const char *format, ...);
功能 将格式化数据写入到文件中(不会输出到终端)
参数 含义
stream 文件指针(已打开的文件流)
format 格式化字符串,定义输出的格式
... 可变参数列表,对应 format 中的占位符
返回值 含义
成功 返回格式化后的字符个数(不包括结尾的 '\0')
失败 返回一个负数(通常是 -1)
注意事项 说明
与 printf 的区别 printf 默认输出到终端(标准输出),fprintf 可指定任意文件流
典型用法 fprintf(fp, "name=%s, age=%d\n", "Tom", 20);
特殊目标 fprintf(stdout, "hello") 等价于 printf("hello");fprintf(stderr, "error") 输出到错误流

八、获取系统时间函数

8.1 time函数

项目 内容
头文件 #include <time.h>
函数原型 time_t time(time_t *tloc);
功能 获取自 1970-01-01 00:00:00 UTC 到当前时刻的秒数(Unix 时间戳)
参数 含义
tloc 若传入非空指针 ,函数会把秒数结果同时写入该指针指向的变量; 若传入 NULL,函数仅返回秒数,不写入任何变量
返回值 含义
成功 返回当前的 Unix 时间戳(秒数,类型为 time_t)
失败 返回 (time_t)-1,并设置相应的错误码(如 errno)
注意事项 说明
典型用法 1 time_t t = time(NULL);(仅获取返回值)
典型用法 2 time_t t; time(&t);(通过指针写入变量)
常见错误 传入未初始化的指针可能导致段错误;应传入有效变量的地址或 NULL
配合函数 常与 localtime()、gmtime()、ctime() 等函数配合,将时间戳转换为可读格式

8.2 localtime函数

项目 内容
头文件 #include <time.h>
函数原型 struct tm *localtime(const time_t *timep);
功能 将 time_t 时间戳转换为本地时区的 struct tm 结构体
参数 含义
timep 指向 time_t 时间戳变量的指针(通常由 time() 函数获取)
返回值 含义
成功 返回指向 struct tm 结构体的指针(内部静态存储,后续调用会覆盖)
失败 返回 NULL,并设置相应的错误码(如 errno)
注意事项 说明
线程不安全 返回的指针指向静态内存,后续调用 localtime 或 gmtime 会覆盖该内存;多线程环境下应使用 localtime_r
时区影响 自动根据系统设置的时区(如 TZ 环境变量)转换时间
典型用法 time_t t = time(NULL); struct tm *tm = localtime(&t);

8.3 struct tm 结构体成员说明

成员 范围 含义
tm_sec 0-60 秒(60 为闰秒)
tm_min 0-59 分
tm_hour 0-23 时
tm_mday 1-31 一个月中的第几天
tm_mon 0-11 月(0 = 1月)
tm_year 年 - 1900 年份(需加 1900 得到实际年份)
tm_wday 0-6 星期几(0 = 星期日)
tm_yday 0-365 一年中的第几天(0 = 1月1日)
tm_isdst 正/0/负 是否夏令时(正值表示启用,0 表示不启用,负值表示未知)

九、文件指针控制函数

9.1 fseek函数

项目 内容
头文件 #include <stdio.h>
函数原型 int fseek(FILE *stream, long offset, int whence);
功能 设置文件流的光标(读写位置)
参数 含义
stream 文件指针(已打开的文件流)
offset 偏移量(单位:字节) • > 0:向后偏移 • = 0:不偏移 • < 0:向前偏移
whence 起始位置(指定从何处开始偏移) • SEEK_SET:从文件开头开始 • SEEK_CUR:从当前位置开始 • SEEK_END:从文件末尾开始
返回值 含义
成功 返回 0
失败 返回 -1,并设置相应的错误码(如 errno)
注意事项 说明
文本模式限制 在 Windows 文本模式(不带 b)下,fseek 的行为可能不符合预期(因换行符转换),建议使用二进制模式或谨慎使用
文件末尾定位 fseek(fp, 0, SEEK_END) 可将光标定位到文件末尾,常用于获取文件大小(配合 ftell)
清除标志 成功调用 fseek 后会清除文件流的文件结束标志
典型用法 fseek(fp, 10, SEEK_SET); // 从开头向后移动 10 字节 fseek(fp, -5, SEEK_CUR); // 从当前位置向前移动 5 字节 fseek(fp, 0, SEEK_END); // 定位到文件末尾

9.2 rewind函数

项目 内容
头文件 #include <stdio.h>
函数原型 void rewind(FILE *stream);
功能 将文件流的光标恢复到文件开头
参数 含义
stream 文件指针(已打开的文件流)
返回值 含义
无 -
注意事项 说明
等价操作 rewind(fp) 等价于 fseek(fp, 0, SEEK_SET)
清除标志 rewind 会同时清除文件流的文件结束标志 和错误标志 (相当于隐式调用了 clearerr)
典型用法 读取完文件一遍后,想重新从头开始读取时使用
示例 rewind(fp); // 光标回到开头,且清除结束/错误标志

9.3 ftell函数

项目 内容
头文件 #include <stdio.h>
函数原型 long ftell(FILE *stream);
功能 返回文件流当前位置相对于文件起始位置的偏移量(以字节为单位)
参数 含义
stream 文件指针(已打开的文件流)
返回值 含义
成功 返回当前光标位置相对于文件开头的字节偏移量
失败 返回 -1,并设置相应的错误码(如 errno)
注意事项 说明
配合 fseek 使用 fseek 定位后,可用 ftell 获取当前位置或文件大小
获取文件大小 fseek(fp, 0, SEEK_END); long size = ftell(fp);
文本模式限制 在 Windows 文本模式(不带 b)下,ftell 返回值可能不准确(因换行符转换),建议使用二进制模式
典型用法 long pos = ftell(fp); // 保存当前位置 fseek(fp, pos, SEEK_SET); // 恢复到之前保存的位置
相关推荐
陈希12312 分钟前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
女神下凡1 小时前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
且从容.4 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道5 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.8 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落9 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨9 小时前
WSL2的安装与使用
linux·wsl
微小的鱼9 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng10 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮10 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频