fopen函数用法详解
fopen函数简介
- 头文件包含
#include <stdio.h>
- 函数定义
FILE *fopen(const char * pathname , const char * mode );
FILE *fdopen(int fd , const char * mode );
FILE *freopen(const char * pathname , const char * mode , FILE * stream );
fopen函数常见使用错误
- 编译错误
warning: implicit declaration of function ‘fopen’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <stdio.h>
fopen函数详细描述
fopen ()函数打开名称为pathname指向的字符串的文件,并将一个流与其关联。
参数mode指向以以下序列之一开头的字符串(后面可能还有其他字符,如下所述):
- 打开文本文件进行阅读。流位于文件的开头。
- r+ 打开读写。流位于文件的开头。
- w 将文件截断为零长度或创建文本文件进行写入。流位于文件的开头。
- w+ 打开读写。如果文件不存在,则创建该文件,否则将截断该文件。流位于文件的开头。
- 打开 a 进行追加(在文件末尾写入)。如果文件不存在,则创建该文件。流位于文件的末尾。
- 打开 a+ 进行读取和追加(在文件末尾写入)。如果文件不存在,则创建该文件。输出总是追加到文件的末尾。POSIX在使用此模式时对初始读取位置保持沉默。对于glibc,读取的初始文件位置在文件的开头,但是对于Android/BSD/macOS,读取的初始文件位置在文件的结尾。
mode字符串还可以包括字母(aqb(aqq)作为最后一个字符或作为上述任何两个字符字符串中字符之间的字符。这严格是为了与C89兼容,没有任何影响;(aqb(aqq)在所有符合POSIX的系统上都被忽略,包括Linux。(其他系统可能会不同地对待文本文件和二进制文件,如果您对二进制文件进行I/O操作,并且希望您的程序可以移植到非UNIX环境中,添加(aqb(aqb(aq)可能是一个好主意。)
有关mode 的glibc扩展的详细信息,请参阅下面的注释
任何创建的文件都将具有模式S_IRUSR " | " S_IWUSR " | " S_IRGRP " | " S_IWGRP " | " S_IROTH " | " S_IWOTH(0666),这是由进程的umask值修改的(请参见umask (2))
读和写可以以任何顺序在读/写流上混合。注意,ANSI C要求文件定位函数介入输出和输入之间,除非输入操作遇到文件末尾。(如果不满足此条件,则允许读取返回除最近写入以外的其他写入结果。)因此,在这样的流上,在写操作和读操作之间放置一个fseek (3)或fgetpos (3)操作是很好的做法(在Linux下有时确实是必要的)。这个操作可能是一个明显的无操作(就像在fseek( 0L SEEK_CUR)中由于其同步副作用而被调用一样)。
以追加模式打开文件(a作为mode )的第一个字符会导致对此流的所有后续写操作发生在文件末尾,就像在调用之前一样:
fseek(stream, 0, SEEK_END);
与流相关联的文件描述符被打开,就像通过使用以下标志调用open (2)一样:.rs.ts Allbox;lb lb c l.fopen()modeopen()标志fdopen()4O_RDONLY fdopen()5o_wronly O_CREAT O_TRUNC ao_wronly O_CREAT O_APPEND r+o_rdwr w+o_rdwr O_CREAT O_TRUNC a+o_rdwr O_CREAT O_APPEND.te.re fdopen ()函数将流与现有的文件描述符相关联,fd 流的mode(值“r”、“r+”、“w”、“w+”、“a”、“a+”之一)必须与文件描述符的模式兼容。新流的文件位置指示符被设置为属于fd 的文件位置指示符,并且清除错误和文件结束指示符。模式“W”或“W+”不会导致截断文件。文件描述符不是dup',并且在关闭由fdopen ()创建的流时将被关闭。将fdopen ()应用于共享内存对象的结果是未定义的。freopen() freopen ()函数打开名称为pathname指向的字符串的文件,并将stream指向的流与其相关联。原始流(如果存在)被关闭。mode参数的使用与fopen ()函数一样。
如果pathname参数是空指针,freopen ()将流的模式更改为mode ;中指定的模式,也就是说,freopen ()重新打开与流关联的路径名。C99标准中增加了这种行为的规范,它说:
.rs在本例中,如果对freopen ()的调用成功,则不需要关闭与流关联的文件描述符。允许哪些模式更改(如果有的话),以及在什么情况下,都是由实现定义的。.Re
freopen ()函数的主要用途是更改与标准文本流相关联的文件。ri(stderr“、”stdin“或”stdout“)。
fopen函数返回值
成功完成后,fopen ()、fdopen ()和freopen ()返回一个FILE指针。否则,返回NULL,并设置errno以指示错误。
fopen函数错误码
- EINVAL 提供给fopen ()、fdopen ()或freopen ()的mode无效。
fopen ()、fdopen ()和freopen ()函数也可能失败,并为例程malloc (3)指定的任何错误设置errno
fopen ()函数也可能失败,并为例程open (2)指定的任何错误设置errno
fdopen ()函数也可能失败,并为例程fcntl (2)指定的任何错误设置errno
freopen ()函数也可能失败,并为例程open (2)、fclose (3)和fflush (3)指定的任何错误设置errno
fopen函数其他说明
GNU C库允许对mode :中指定的字符串进行以下扩展
- c " (since glibc 233)"不做打开操作,或后续的读写操作,线程取消点。对fdopen ()忽略此标志
- e " (since glibc 27)"用 O_CLOEXEC 标志打开文件。有关更多信息,请参见open (2)。fdopen ()忽略此标志
- m " (since glibc 23)"尝试使用mmap (2)而不是I/O系统调用( read (2) write (2))来访问文件。
- x 以独占方式打开文件(如open (2))的 O_EXCL 标志,如果文件已经存在,fopen ()失败,并将errno设置为EEXIST ,对于fdopen ()此标志被忽略
除上述字符外,fopen ()和freopen ()在mode :中支持以下语法
.bi“,ccs=”字符串
给定的string作为编码字符集的名称,并将流标记为面向广泛的。此后,如果没有指定。bi,ccs=string语法,则内部转换函数将I/O与字符集string 进行转换,然后由第一个文件操作确定流的宽方向。如果该操作是宽字符操作,则将流标记为面向宽,并加载转换为编码字符集的函数。
评论区