命名空间
变体
操作

fopen, fopen_s

来自 cppreference.cn
< c‎ | io
 
 
文件输入/输出
类型和对象
        
函数
文件访问
fopenfopen_s
(C11)
(C95)
非格式化输入/输出
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

格式化输入
 
定义于头文件 <stdio.h>
(1)
FILE *fopen( const char *filename, const char *mode );
(直到 C99)
FILE *fopen( const char *restrict filename, const char *restrict mode );
(自 C99 起)
errno_t fopen_s( FILE *restrict *restrict streamptr,

                 const char *restrict filename,

                 const char *restrict mode );
(2) (自 C11 起)
1) 打开由 filename 指示的文件,并返回与该文件关联的文件流的指针。 mode 用于确定文件访问模式。
2)(1) 相同,不同之处在于文件流的指针被写入 streamptr,并且在运行时检测到以下错误并调用当前安装的 约束处理函数
  • streamptr 是空指针
  • filename 是空指针
  • mode 是空指针
与所有边界检查函数一样,只有当实现定义了 __STDC_LIB_EXT1__ 并且用户在包含 <stdio.h> 之前将 __STDC_WANT_LIB_EXT1__ 定义为整数常量 1 时,才能保证 fopen_s 可用。

目录

[编辑] 参数

filename - 与文件流关联的文件名
mode - 确定 文件访问模式 的空终止字符字符串
streamptr - 指向函数存储结果的指针(输出参数)

[编辑] 文件访问标志

文件访问
mode 字符串
含义 解释 文件操作
已存在
文件操作
不存在
"r" 读取 打开文件以进行读取 从头开始读取 打开失败
"w" 写入 创建文件以进行写入 销毁内容 创建新文件
"a" 追加 追加到文件 写入到末尾 创建新文件
"r+" 扩展读取 打开文件以进行读/写 从头开始读取 错误
"w+" 扩展写入 创建文件以进行读/写 销毁内容 创建新文件
"a+" 扩展追加 打开文件以进行读/写 写入到末尾 创建新文件
文件访问模式标志 "b" 可以选择性地指定以二进制模式打开文件。此标志在 POSIX 系统上无效,但在 Windows 上,它禁用对 '\n''\x1A' 的特殊处理。
在追加文件访问模式下,数据被写入文件的末尾,而与文件位置指示器的当前位置无关。
如果模式不是上面列出的字符串之一,则行为未定义。某些实现定义了其他支持的模式(例如 Windows)。
在更新模式 ('+') 下,可以执行输入和输出,但输出之后不能紧跟输入,除非中间调用了 fflushfseekfsetposrewind。输入之后也不能紧跟输出,除非中间调用了 fseekfsetposrewind,除非输入操作遇到文件结尾。在更新模式下,即使指定了文本模式,也允许实现使用二进制模式。
文件访问模式标志 "x" 可以选择性地附加到 "w""w+" 说明符。如果文件存在,则此标志强制函数失败,而不是覆盖它。 (C11)
当使用 fopen_sfreopen_s 时,使用 "w""a" 创建的任何文件的文件访问权限都会阻止其他用户访问它。文件访问模式标志 "u" 可以选择性地添加到任何以 "w""a" 开头的说明符之前,以启用默认的 fopen 权限。 (C11)

[编辑] 返回值

1) 如果成功,则返回指向新文件流的指针。除非 filename 引用交互设备,否则流是完全缓冲的。如果出错,则返回空指针。POSIX 要求 在这种情况下设置 errno
2) 如果成功,则返回零,并将指向新文件流的指针写入 *streamptr。如果出错,则返回非零错误代码,并将空指针写入 *streamptr(除非 streamptr 本身是空指针)。

[编辑] 注意

filename 的格式是实现定义的,并且不一定是指文件(例如,它可能是控制台或可通过文件系统 API 访问的其他设备)。在支持它们的平台上,filename 可以包含绝对或相对文件系统路径。

[编辑] 示例

#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    const char* fname = "/tmp/unique_name.txt"; // or tmpnam(NULL);
    int is_ok = EXIT_FAILURE;
 
    FILE* fp = fopen(fname, "w+");
    if (!fp)
    {
        perror("File opening failed");
        return is_ok;
    }
    fputs("Hello, world!\n", fp);
    rewind(fp);
 
    int c; // note: int, not char, required to handle EOF
    while ((c = fgetc(fp)) != EOF) // standard C I/O file reading loop
        putchar(c);
 
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
    {
        puts("End of file is reached successfully");
        is_ok = EXIT_SUCCESS;
    }
 
    fclose(fp);
    remove(fname);
    return is_ok;
}

可能的输出

Hello, world!
End of file is reached successfully

[编辑] 参考文献

  • C17 标准 (ISO/IEC 9899:2018)
  • 7.21.5.3 fopen 函数 (p: 223-224)
  • K.3.5.2.1 fopen_s 函数 (p: 428-429)
  • C11 标准 (ISO/IEC 9899:2011)
  • 7.21.5.3 fopen 函数 (p: 305-306)
  • K.3.5.2.1 fopen_s 函数 (p: 588-590)
  • C99 标准 (ISO/IEC 9899:1999)
  • 7.19.5.3 fopen 函数 (p: 271-272)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 4.9.5.3 fopen 函数

[编辑] 参见

关闭文件
(函数) [编辑]
将输出流与实际文件同步
(函数) [编辑]
使用不同的名称打开现有流
(函数) [编辑]
C++ 文档 关于 fopen