C 风格文件输入/输出 (std::fopen)(std::freopen)(std::fclose)

文件访问

打开文件

std::fopen

std::FILE* fopen( const char* filename, const char* mode );

打开 filename 所指示的文件并返回与该文件关联的流。用 mode 确定文件访问模式。

参数

filename - 要关联文件流到的文件名
mode - 确定文件访问模式的空终止字符串
文件访问模式字符串 含义 解释 若文件已存在的行动 若文件不存在的行动
"r" 为读取打开文件 从起始读取 打开失败
"w" 为写入创建文件 销毁内容 创建新文件
"a" 追加 追加到文件 写入到末尾 创建新文件
"r+" 扩展读 为读取/写入打开文件 从起始读取 错误
"w+" 扩展写 为读取/写入创建文件 销毁内容 创建新文件
"a+" 扩展追加 为读取/写入打开文件 写入到末尾 创建新文件
文件访问模式标志 "b" 能可选地指定,以用二进制模式打开文件。此标志在 POSIX 系统上无效果,但例如在 Windows 上,它禁用 '\n' 和 '\x1A' 的特殊处理。
在追加文件访问模式上,写入数据到文件尾,忽略文件位置指示器的当前位置。
文件访问模式标志 "x" 能可选地追加到 "w" 或 "w+" 指定符。此标志强制函数在文件存在的情况下失败,而非重写文件。(C++17)
若模式不是以上字符串之一,则行为未定义。一些实现定义额外的

返回值

若成功,则返回指向控制打开的文件流的对象的指针,并清除文件尾和错误位。流为完全缓冲,除非 filename 指代交互设备。

错误时,返回空指针。 POSIX 要求此情况下设置 errno 。

注意

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

可移植的目录和文件命名,见 C++ 文件系统库或 boost.filesystem

调用示例

#include <cstdio>
#include <cstdlib>

int main()
{
    FILE* fp = std::fopen("test.txt", "r");
    if (!fp)
    {
        std::perror("File opening failed");
        return EXIT_FAILURE;
    }

    int c; // 注意:是 int 而非 char ,要求处理 EOF
    while ((c = std::fgetc(fp)) != EOF)   // 标准 C I/O 文件读取循环
    {
        std::putchar(c);
    }

    if (std::ferror(fp))
    {
        std::puts("I/O error when reading");
    }
    else if (std::feof(fp))
    {
        std::puts("End of file reached successfully");
    }

    std::fclose(fp);
    return 0;
}

输出

以不同名称打开既存流

std::freopen

std::FILE* freopen( const char* filename, const char* mode, std::FILE* stream );

首先,试图关闭与 stream 关联的文件,忽略任何错误。然后,若 filename 非空,则试图用 mode 打开 filename 所指定的文件,如同用 fopen ,然后将该文件与 stream 所指向的文件流关联。若 filename 为空指针,则函数试图重打开已与 stream 关联的文件(此情况下是否允许模式改变是实现定义的)。

参数

filename - 要关联文件流到的文件
mode - 确定新文件打开模式的空终止字符串

文件访问模式字符串 含义 解释 若文件已存在的行动 若文件不存在的行动
"r" 为读取打开文件 从起始读取 打开失败
"w" 为写入创建文件 销毁内容 创建新文件
"a" 追加 追加到文件 写入到末尾 创建新文件
"r+" 扩展读 为读取/写入打开文件 从起始读取 错误
"w+" 扩展写 为读取/写入创建文件 销毁内容 创建新文件
"a+" 扩展追加 为读取/写入打开文件 写入到末尾 创建新文件
文件访问模式标志 "b" 能可选地指定,以用二进制模式打开文件。此标志在 POSIX 系统上无效果,但例如在 Windows 上,它禁用 '\n' 和 '\x1A' 的特殊处理。
在追加文件访问模式上,写入数据到文件尾,忽略文件位置指示器的当前位置。
文件访问模式标志 "x" 能可选地追加到 "w" 或 "w+" 指定符。此标志强制函数在文件存在的情况下失败,而非重写文件。(C++17)
若模式不是以上字符串之一,则行为未定义。一些实现定义额外的支持模式(例如 MSVC )。

stream - 要修改的文件流

返回值

成功时为 stream ,失败时为 NULL 。

注意

freopen 是一旦由 I/O 操作或 std::fwide 建立面向后,改变流窄/宽面向的唯一方式。

调用示例

#include <cstdio>

int main()
{
    std::printf("stdout is printed to console\n");
    if (std::freopen("redir.txt", "w", stdout))
    {
        std::printf("stdout is redirected to a file\n"); // 这被写入 redir.txt
        std::fclose(stdout);
    }
    return 0;
}

 输出

关闭文件

std::fclose

int fclose( std::FILE* stream );

关闭给定的文件流。冲入任何未写入的缓冲数据到 OS 。舍弃任何未读取的缓冲数据。

无论操作是否成功,流都不再关联到文件,且由 std::setbuf 或 std::setvbuf 分配的缓冲区若存在,则亦被解除关联,并且若使用自动分配则被解分配。

若在 fclose 返回后使用 stream 的值则行为未定义。

参数

stream - 要关闭的文件流

返回值

成功时为 ​0​ ,否则为 EOF 。

调用示例

#include <cstdio>
#include <cstdlib>

int main()
{
    FILE* fp = std::fopen("test.txt", "r");
    if (!fp)
    {
        std::perror("File opening failed");
        return EXIT_FAILURE;
    }

    int c; // 注意:是 int 而非 char ,要求处理 EOF
    while ((c = std::fgetc(fp)) != EOF)   // 标准 C I/O 文件读取循环
    {
        std::putchar(c);
    }

    if (std::ferror(fp))
    {
        std::puts("I/O error when reading");
    }
    else if (std::feof(fp))
    {
        std::puts("End of file reached successfully");
    }

    std::fclose(fp);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/132630830