Namespaces
Variants

fopen, fopen_s

来自 zh.cppreference.net
< c | io
 
 
文件输入/输出
类型和对象
        
函数
文件访问
(C95)
无格式输入/输出
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

格式化输入
 
在头文件中定义 <stdio.h>
FILE* fopen( const char* filename, const char* mode );
(1) (直到 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 是空指针
如同所有边界检查函数一样,fopen_s 仅在以下情况下保证可用:__STDC_LIB_EXT1__ 由实现定义,并且用户定义了 __STDC_WANT_LIB_EXT1__ 为整数常量 1,在包含 <stdio.h> 之前。

参数

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 要求 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

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • 7.21.5.3 fopen 函数 (p: 待定)
  • K.3.5.2.1 fopen_s 函数 (p: 待定)
  • 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++ 文档 for fopen