Namespaces
Variants

fopen, fopen_s

From cppreference.net
< c ‎ | io
定义于头文件 <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 - 函数存储结果的指针地址(输出参数)

文件访问标志

文件访问
模式字符串
含义 说明 文件已存在时的操作 文件不存在时的操作
"r" read 打开文件用于读取 从起始位置读取 打开失败
"w" write 创建文件用于写入 销毁内容 创建新文件
"a" append 追加到文件 写入到末尾 创建新文件
"r+" read extended 打开文件用于读写 从起始位置读取 错误
"w+" write extended 创建文件用于读写 销毁内容 创建新文件
"a+" append extended 打开文件用于读写 写入到末尾 创建新文件
文件访问模式标志 "b" 可选择性地指定以二进制模式打开文件。该标志在 POSIX 系统上无效,但在 Windows 上会禁用对 ' \n ' ' \x1A ' 的特殊处理。
在追加文件访问模式下,无论文件位置指示器的当前位置如何,数据都将写入文件末尾。
如果模式不是上述列出的字符串之一,则行为未定义。某些实现定义了额外支持的模式(例如 Windows )。
在更新模式( '+' )下,可以同时进行输入和输出,但输出后若不调用 fflush fseek fsetpos rewind 则不能立即进行输入;输入后若不调用 fseek fsetpos rewind 则不能立即进行输出,除非输入操作已遇到文件结尾。在更新模式下,即使指定了文本模式,实现也允许使用二进制模式。
文件访问模式标志 "x" 可选择性地附加到 "w" "w+" 说明符后。此标志强制函数在文件已存在时失败,而不是覆盖文件。 (C11)
当使用 fopen_s freopen_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"; // 或使用 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; // 注意:必须使用 int 类型而非 char 类型来处理 EOF
    while ((c = fgetc(fp)) != EOF) // 标准 C I/O 文件读取循环
        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 函数 (页码: 223-224)
  • K.3.5.2.1 fopen_s 函数 (页码: 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函数(页码:271-272)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 4.9.5.3 fopen 函数

参见

关闭文件
(函数)
将输出流与实际文件同步
(函数)
使用不同名称重新打开现有流
(函数)
C++ 文档 for fopen