标准I/O的函数都存在于标准I/O库中。这些库函数处理了I/O 的一些细节,如缓冲区 的分配、设置最佳的缓冲区大小等,为用户避免了考虑这些琐事的烦恼,使用起来更简单, 更方便。
另外,标准I/O库是使用标准C语言书写的,所以它不仅可以应用于Linux系统中,而 且也可以用于其他的系统(如Windows系统)。而基于文件系统的I/O与操作系统有很大关 系,不能应用于其他系统。因此,标准I/O的应用范围更广泛。
一、概念
- 在C库中定义的一组用于输入输出的函数接口
二、特点⭐⭐⭐
- 1)通过缓冲机制减少系统调用,提高效率
- 2)围绕流进行操作,流用**FILE ***表示。
- 3)标准IO默认打开了三个流,分别是标准输入stdin,标准输出stdout,标准错误stderr
三、缓冲区⭐⭐⭐
3.1 全缓冲
-
针对文件
-
刷新条件
- 程序正常结束
- 缓冲区满刷新
- 强制刷新:fflush
3.1 行缓冲
-
针对终端
-
刷新条件
3.3 不缓冲
- 没缓冲区,标准错误
四、函数接口⭐⭐⭐⭐
4.1 打开
4.1.1 fopen
-
**FILE *fopen(const char path, const char mode)
-
功能
- 打开文件
-
参数
-
path:打开的文件
-
mode:打开的方式
- r/rb:只读,当文件不存在时报错,文件流定位到文件开头
- r+/r+b:可读可写,当文件不存在时报错,文件流定位到文件开头
- w/wb:只写,文件不存在创建,存在清空
- w+/w+b:可读可写,文件不存在创建,存在清空
- a/ab:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾
- a+/a+b:读和追加,文件不存在创建,存在追加,🚨📢👉读文件流定位到文件开头,写文件流定位到文件末尾
-
-
返回值
- 成功:文件流指针
- 失败:NULL,并且会设置错误码
-
例
4.1.2 freopen
-
*FILE * freopen(const char pathname, const char mode, FILE fp)
-
功能:将指定的文件流重定向到打开的文件中
-
参数
- path:文件路径
- mode:打开文件的方式(同fopen)
- fp:文件流指针
-
返回值
- 成功:返回文件流指针
- 失败:NULL
-
- /dev/tty是一个特殊文件,代表当前正在使用的终端设备
4.1.2 容错机制perror
-
perror是一个库函数,这个函数内部会自己获取errno的值,调用这个函数会直接把错误提示字符串打印出来。此外,我们也可以在错误提示字符串前添加一些自己想要打印的信息→perror("fopen err");
-
man手册信息
4.2 关闭
4.2.1 fclose
-
int fclose(FILE stream);*
-
功能
- 关闭文件
-
参数
- stream:文件流
-
返回值
-
成功
- 返回0
-
失败
- 返回EOF
-
4.3 读写操作
4.3.1 字符I/O
-
fgetc
-
int fgetc(FILE * stream)
-
功能:从文件中读取一个字符
-
参数:stream:文件流
-
返回值:
- 成功:整型,即读到的字符的ASCII码值
- 文件结束或出现错误返回EOF
-
-
fputc
-
int fputc(int c, FILE * stream)
-
功能:向文件流stream中写入一个字符c
-
参数
- c:要写的字符的ASCII码值,或者直接写 '字符'
- stream:文件流
-
返回值
- 成功:写的字符的ASCII码值
- 失败:EOF
-
-
练习1
-
练习2
4.3.2 行I/O
-
fgets
-
*char * fgets(char s, int size, FILE * stream);
-
功能:从文件流中每次读取一行字符串至s所指向的字符串中
-
参数
- s:存放字符串的地址
- size:一次读取的字符串s的大小
- stream:文件流指针
-
返回值
- 成功:s的地址
- 失败或读到文件末尾:NULL
-
特性
- 该函数从流中连续读字符直至读到换行符'\n'或者读够size-1个字符(包括换行符)为止。所读入的这一行字符,包括最后的换行符,存储在s指定的字符串中,并且在其末尾添加一个空字符'\0'作为该字符串的结束标志。 如果要读入的这一行,包括结尾的换行符,长度大于size-1,则只有部分字符(size-1个)被读入。下次调用将返回此行剩余部分。
-
-
fputs
-
*int fputs(const char s, FILE * stream);
-
功能:把以空字符(\0)结尾的字符串输出到指定文件流中,末尾的空字符(\0)并不输出。 由于字符串并没有要求一定换行符为结尾,所以这个函数也不一定是一次输出一行的。
-
参数
- s:要写的内容
- stream:文件流
-
返回值
- 成功:非负整数
- 失败:EOF
-
-
练习
4.3.3 块I/O
-
fread
-
**size_t fread(void ptr, size_t size, size_t nmemb, FILE stream);
-
功能:从stream文件流读取nmenb个数据项存放至ptr所指的数组中,其中每一项数据长度为size大小,故所读取总字节数为size*nmemb
-
参数
- ptr :用来存放读取元素
- size :元素大小,用sizeof(数据类型)表示
- nmemb :读取元素的个数
- stream :要读取的文件流指针
-
返回值
- 成功:读取的元素的个数
- 读到文件尾: 0
- 失败: -1
-
-
fwrite
-
**size_t fwrite(const void ptr, size_t size, size_t nmemb, FILE stream);
-
功能:从ptr所指的数组中写出nmemb个数据项至stream指定的流
-
参数
- 和fread一样
-
返回值
- 成功:写的元素个数
- 失败 :-1
-
-
例
-
练习:实现cp fread fwrite 复制一张图片
4.4 定位操作
-
rewind
- *void rewind(FILE stream);
- 功能:将文件位置指针定位到起始位置
-
fseek
-
*int fseek(FILE stream, long offset, int whence);
-
功能:文件的定位操作
-
参数
-
stream:文件流
-
offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
-
whence:相对位置:
- SEEK_SET:相对于文件开头
- SEEK_CUR:相对于文件当前位置
- SEEK_END:相对于文件末尾
-
返回值
- 成功:0
- 失败:-1
-
📢注:当打开文件的方式为a或a+时,fseek不起作用
-
-
-
ftell
-
*long ftell(FILE stream);
-
功能:获取当前的文件位置
-
参数:要检测的文件流
-
返回值
- 成功:当前的文件位置(从文件开始到当前文件流的字节数)
- 出错:-1
-
-
获取文件长度
-
例