46 C 语言文件的打开与关闭、写入与读取函数:fopen、fclose、fputc、fputs、fprintf、fgetc、fgets、fscanf

目录

[1 文件的存储形式](#1 文件的存储形式)

[2 打开文件------fopen() 函数](#2 打开文件——fopen() 函数)

[2.1 功能描述](#2.1 功能描述)

[2.2 函数原型](#2.2 函数原型)

[2.3 文件打开方式(模式)](#2.3 文件打开方式(模式))

[3 关闭文件------fclose() 函数](#3 关闭文件——fclose() 函数)

[3.1 功能描述](#3.1 功能描述)

[3.2 函数原型](#3.2 函数原型)

[4 常见的文件写入方式](#4 常见的文件写入方式)

[4.1 fputc() 函数](#4.1 fputc() 函数)

[4.1.1 功能描述](#4.1.1 功能描述)

[4.1.2 函数原型](#4.1.2 函数原型)

[4.1.3 案例演示](#4.1.3 案例演示)

[4.2 fputs() 函数](#4.2 fputs() 函数)

[4.2.1 功能说明](#4.2.1 功能说明)

[4.2.2 函数原型](#4.2.2 函数原型)

[4.2.3 案例演示](#4.2.3 案例演示)

[4.3 fprintf() 函数](#4.3 fprintf() 函数)

[4.3.1 功能说明](#4.3.1 功能说明)

[4.3.2 函数原型](#4.3.2 函数原型)

[4.3.3 案例演示](#4.3.3 案例演示)

[4.4 文件写入------综合案例演示](#4.4 文件写入——综合案例演示)

[5 常见的文件写入方式](#5 常见的文件写入方式)

[5.1 fgetc() 函数](#5.1 fgetc() 函数)

[5.1.1 功能说明](#5.1.1 功能说明)

[5.1.2 函数原型](#5.1.2 函数原型)

[5.1.3 案例演示](#5.1.3 案例演示)

[5.2 fgets() 函数](#5.2 fgets() 函数)

[5.2.1 功能说明](#5.2.1 功能说明)

[5.2.2 函数原型](#5.2.2 函数原型)

[5.2.3 案例演示](#5.2.3 案例演示)

[5.3 fscanf 函数](#5.3 fscanf 函数)

[5.2.1 功能说明](#5.2.1 功能说明)

[5.2.2 函数原型](#5.2.2 函数原型)

[5.2.3 案例演示](#5.2.3 案例演示)


1 文件的存储形式

文件,无论是文本文件还是二进制文件,都是以连续的字节序列形式存储在存储设备上的。这种存储方式确保了文件内容的完整性和可访问性,同时也为高效的文件管理和操作提供了基础。C 语言为此提供了一套全面且强大的函数库,使得开发者能够方便地进行文件的读取、写入、更新等操作。

  • 文本文件 :通常由人类可读的字符组成,每个字符占用一个字节(在 ASCII 编码中)或多个字节(在 Unicode 编码中)。文本文件通常用于存储源代码、配置信息、日志记录等。在不同的操作系统中,文本文件的换行符可能有所不同(例如,Windows 使用 \r\n,而 Unix/Linux 使用 \n)。
  • 二进制文件 :可以包含任何类型的字节序列,包括非打印字符。二进制文件通常用于存储图像、音频、视频等多媒体数据,以及编译后的程序代码。由于二进制文件的内容不是人类直接可读的,因此在读写时需要特别注意数据的格式和结构。

2 打开文件------fopen() 函数

2.1 功能描述

fopen() 函数主要用于打开一个文件,或者创建一个新文件。它允许程序以读取、写入或追加的方式访问文件。如果指定的文件不存在,某些模式下 fopen() 可能会创建该文件。如果文件存在,某些模式可能会清除文件内容或在文件末尾追加内容。

2.2 函数原型

cpp 复制代码
#include <stdio.h>
FILE *fopen(const char *filename, const char *mode);

参数:

  • filename :一个指向以 null 结尾的字符串的指针,该字符串包含了要打开的文件的路径(位置 + 名称),路径可以是绝对路径,也可以是相对路径。
    • 绝对路径 :从根目录开始的完整路径。在 Unix/Linux 系统中使用正斜杠 /,在 Windows 系统中可以使用反斜杠 \,但需要注意使用转义字符 \\,或者使用正斜杠 / 也是兼容的。
    • 相对路径:相对于当前工作目录的路径。
  • mode :一个指向以 null 结尾的字符串的指针,该字符串指定了打开文件的方式。详情见表2.3。

返回值:

  • 成功时返回一个指向 FILE 类型的指针,表示已打开的文件流。
  • 失败时返回 NULL。

2.3 文件打开方式(模式)

模式 描述
r 只读模式。 打开一个已存在的文本文件,只允许读取文件。如果文件不存在,则打开失败。
w 只写模式。 打开一个文本文件,从头写入文件。如果文件不存在,则会创建一个新文件并写入;如果文件存在,则清空文件并从头写入。
a 追加模式。 打开一个文本文件,追加写入文件。如果文件不存在,则会创建一个新文件并写入;如果文件存在,在已有内容后面追加写入。
rb 只读二进制模式。 打开一个已存在的二进制文件,只允许读取文件。如果文件不存在,则打开失败。
wb 只写二进制模式。 打开一个二进制文件,从头写入文件。如果文件不存在,则会创建一个新文件并写入;如果文件存在,则清空文件并从头写入。
ab 追加二进制模式。 打开一个二进制文件,追加写入文件。如果文件不存在,则会创建一个新文件并写入;如果文件存在,在已有内容后面追加写入。
r+ 读写模式。 打开一个已存在的文本文件,允许读写文件。文件指针位于文件开头。如果文件不存在,则打开失败。
w+ 读写模式。 打开一个文本文件,从头读写文件。如果文件不存在,则会创建一个新文件并读写;如果文件存在,则清空文件并从头读写。
a+ 读写模式。 打开一个文本文件,读取或追加写入文件。如果文件不存在,则会创建一个新文件并读写;如果文件存在,文件指针位于文件末尾,读取时从开头开始,写入时在已有内容后面追加。
rb+ 读写二进制模式。 打开一个已存在的二进制文件,允许读写文件。文件指针位于文件开头。如果文件不存在,则打开失败。
r+b 读写二进制模式。 同 rb+,允许读写二进制文件。
wb+ 读写二进制模式。 打开一个二进制文件,从头读写文件。如果文件不存在,则会创建一个新文件并读写;如果文件存在,则清空文件并从头读写。
w+b 读写二进制模式。 同 wb+,允许读写二进制文件。
ab+ 读写二进制模式。 打开一个二进制文件,读取或追加写入文件。如果文件不存在,则会创建一个新文件并读写;如果文件存在,文件指针位于文件末尾,读取时从开头开始,写入时在已有内容后面追加。
a+b 读写二进制模式。 同 ab+,允许读写二进制文件。

补充说明:

  • 文件指针位置 :在某些模式下,文件指针的位置是固定的。例如,在 aa+ 模式下,文件指针默认位于文件末尾,但在读取时可以从文件开头开始。
  • 文件创建 :在 waw+a+wbabwb+ab+ 模式下,如果文件不存在,fopen() 会创建一个新文件。
  • 文件清空 :在 ww+wbwb+ 模式下,如果文件已经存在,fopen() 会清空文件内容。
  • 文本与二进制模式 :文本模式(rwar+w+a+)在某些系统上会对换行符进行转换,而二进制模式(rbwbabrb+wb+ab+)则不会进行任何转换。
  • 不会创建目录 :无论使用哪种模式,fopen 函数都不会创建目录。fopen 只负责打开或创建文件,但不会创建文件路径中不存在的目录。如果指定的路径中的某个目录不存在,fopen 会失败并返回 NULL。
  • 读文件 :从文件中读取数据到内存中,对于内存来说是输入流。
  • 写文件 :将内存中的数据写入到文件中,对于内存来说是输出流。

3 关闭文件------fclose() 函数

3.1 功能描述

fclose() 函数的主要功能是关闭一个文件流。当文件流被关闭时,所有未写入磁盘的缓冲区数据会被刷新,文件指针和相关资源会被释放。关闭文件是一个重要的步骤,可以避免资源泄漏和数据丢失。

3.2 函数原型

cpp 复制代码
#include <stdio.h>
int fclose(FILE *stream);

参数:

  • stream :一个指向 FILE 类型的指针,表示要关闭的文件流。这个指针通常是通过 fopen() 函数获得的。

返回值:

  • 如果文件成功关闭,返回 0。
  • 如果关闭文件时发生错误,返回 EOF(通常定义为 -1)。

4 常见的文件写入方式

4.1 fputc() 函数

4.1.1 功能描述

fputc() 函数的主要功能是将一个字符写入指定的文件流中。如果写入成功,该函数返回写入的字符;如果写入失败,返回 EOF。

4.1.2 函数原型

cpp 复制代码
#include <stdio.h>
int fputc(int c, FILE *stream);

参数:

  • c :要写入的字符。虽然参数类型是 int,但实际上传递的是一个字符(char 类型),因为 EOF 也是一个 int 类型的特殊值。
  • stream :一个指向 FILE 类型的指针,表示要写入的文件流。这个指针通常是通过 fopen() 函数获得的。

返回值:

  • 如果字符成功写入文件,返回写入的字符(转换为 unsigned char 后再转换为 int)。
  • 如果写入失败,返回 EOF(通常定义为 -1)。

4.1.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 打开文件,使用追加模式('a')。如果文件不存在,则会创建一个新文件
    // 如果文件存在,则会在文件末尾追加内容
    // 如果指定的路径中的某个目录不存在,fopen 会失败,并返回 NULL
    FILE *file = fopen("./path/files/output1.txt", "a"); // 追加写入

    // 检查文件是否成功打开
    if (file != NULL)
    {
        // 定义要写入的字符
        char ch = 'A';

        // 使用 fputc 函数写入一个字符
        int result1 = fputc(ch, file);

        // 检查 fputc 是否成功
        if (result1 != EOF)
        {
            // 如果写入成功,输出成功信息及返回值
            printf("成功使用 fputc 写入字符 '%c',返回值:%d。\n", ch, result1);
        }
        else
        {
            // 如果写入失败,输出错误信息
            printf("使用 fputc 写入字符时出现错误。\n");
        }

        // 关闭文件
        fclose(file);
    }
    else
    {
        // 如果文件打开失败,输出错误信息
        printf("打开文件时出现错误。\n");
    }

    return 0;
}

输出结果如下所示:

4.2 fputs() 函数

4.2.1 功能说明

fputs() 函数的主要功能是将一个字符串(不包括终止的空字符 '\0')写入指定的文件流中,如果字符串中包含换行符 '\n',fputs 会将其原样写入文件。如果写入成功,该函数返回一个非负值;如果写入失败,返回 EOF。

4.2.2 函数原型

cpp 复制代码
#include <stdio.h>
int fputs(const char *str, FILE *stream);

参数:

  • str :一个指向以 null 结尾的字符串的指针,表示要写入的字符串。
  • stream :一个指向 FILE 类型的指针,表示要写入的文件流。这个指针通常是通过 fopen() 函数获得的。

返回值:

  • 如果字符串成功写入文件,返回一个非负值(通常是成功写入的字符数,具体取决于编译器)。
  • 如果写入失败,返回 EOF(通常定义为 -1)。

4.2.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 打开文件,使用写入模式('w')。如果文件存在,则清空文件;如果文件不存在,则创建新文件
    FILE *file = fopen("./path/files/output2.txt", "w"); // 从头写入

    if (file != NULL)
    {
        // 定义要写入的字符串
        const char *text = "使用写入模式('w')。如果文件存在,则清空文件;如果文件不存在,则创建新文件\n";

        // 使用 fputs 函数写入字符串
        int result = fputs(text, file);

        // 检查 fputs 是否成功
        if (result != EOF)
        {
            // 如果写入成功,输出成功信息及返回值
            printf("成功使用 fputs 写入字符串,返回值:%d。\n", result);
        }
        else
        {
            // 如果写入失败,输出错误信息
            printf("使用 fputs 写入字符串时出现错误。\n");
        }

        // 关闭文件
        fclose(file);
    }
    else
    {
        // 如果文件打开失败,输出错误信息
        printf("打开文件时出现错误。\n");
    }

    return 0;
}

输出结果如下所示:

4.3 fprintf() 函数

4.3.1 功能说明

fprintf() 函数的主要功能是将格式化的字符串写入指定的文件流中,如果格式化字符串中包含换行符 '\n',fprintf 会将其原样写入文件。它可以接受多个参数,并根据提供的格式字符串将这些参数格式化后写入文件。如果写入成功,该函数返回写入的字符数;如果写入失败,返回一个负值。

4.3.2 函数原型

cpp 复制代码
#include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);

参数:

  • stream :一个指向 FILE 类型的指针,表示要写入的文件流。这个指针通常是通过 fopen() 函数获得的。
  • format:一个指向以 null 结尾的字符串的指针,表示格式化字符串。格式化字符串可以包含普通字符和格式化说明符(如 %d、%s、%f 等),与 printf 类似。
  • ...:可变参数列表,根据格式化字符串中的说明符提供相应的参数,与 printf 类似。

返回值:

  • 如果写入成功,返回写入的字符数(不包括终止符 '\0')。
  • 如果写入失败,返回一个负值。

4.3.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 打开文件,使用写入模式('w')。如果文件存在,则清空文件;如果文件不存在,则创建新文件
    FILE *file = fopen("./path/files/output3.txt", "w"); // 从头写入

    if (file != NULL)
    {
        // 定义要写入的格式化字符串
        const char *text = "fprintf: %s is studying in CSDN_Thanks_ks\n";
        char *name = "Alice";

        // 使用 fprintf 函数写入格式化的字符串
        int result = fprintf(file, text, name);

        // 检查 fprintf 是否成功
        if (result != EOF)
        {
            // 如果写入成功,输出成功信息及返回值
            printf("成功使用 fprintf 写入字符串,返回值:%d。\n", result);
        }
        else
        {
            // 如果写入失败,输出错误信息
            printf("使用 fprintf 写入字符串时出现错误。\n");
        }

        // 关闭文件
        fclose(file);
    }
    else
    {
        // 如果文件打开失败,输出错误信息
        printf("打开文件时出现错误。\n");
    }

    return 0;
}

输出结果如下所示:

4.4 文件写入------综合案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 以追加模式('a')打开文件。如果文件不存在,则会创建一个新文件
    // 如果文件存在,则会在文件末尾追加内容
    FILE *file = fopen("./path/files/output4.txt", "a"); // 追加写入

    if (file != NULL)
    {
        // 使用 fputc 写入一个字符
        char ch = 'A';
        int result1 = fputc(ch, file);

        if (result1 != EOF)
        {
            // 如果 fputc 成功,输出成功信息及返回值
            printf("成功使用 fputc 写入字符 '%c',返回值:%d。\n", ch, result1);
        }
        else
        {
            // 如果 fputc 失败,输出错误信息
            printf("使用 fputc 写入字符时出现错误。\n");
        }

        // 使用 fputs 写入一个字符串
        const char *text = "fputs: Welcome to my blog, I am Thanks_ks\n";
        int result2 = fputs(text, file);

        if (result2 != EOF)
        {
            // 如果 fputs 成功,输出成功信息及返回值
            printf("成功使用 fputs 写入字符串,返回值:%d。\n", result2);
        }
        else
        {
            // 如果 fputs 失败,输出错误信息
            printf("使用 fputs 写入字符串时出现错误。\n");
        }

        // 使用 fprintf 写入格式化数据
        int num = 42;
        float pi = 3.14159;
        const char *formattedText = "fprintf: %d %.2f\n";
        int result3 = fprintf(file, formattedText, num, pi);

        if (result3 >= 0)
        {
            // 如果 fprintf 成功,输出成功信息及返回值
            printf("成功使用 fprintf 写入格式化数据,返回值:%d。\n", result3);
        }
        else
        {
            // 如果 fprintf 失败,输出错误信息
            printf("使用 fprintf 写入格式化数据时出现错误。\n");
        }

        // 关闭文件,释放与文件相关的资源
        fclose(file);
    }
    else
    {
        // 如果文件打开失败,输出错误信息
        printf("打开文件时出现错误。\n");
    }

    return 0;
}

输出结果如下所示:


5 常见的文件写入方式

5.1 fgetc() 函数

5.1.1 功能说明

fgetc() 函数的主要功能是从指定的文件流中读取一个字符。如果读取成功,该函数返回读取到的字符;如果到达文件末尾或发生错误,返回 EOF。

5.1.2 函数原型

cpp 复制代码
#include <stdio.h>
int fgetc(FILE *stream);

参数:

  • stream :一个指向 FILE 类型的指针,表示要读取的文件流。这个指针通常是通过 fopen() 函数获得的。

返回值:

  • 如果读取成功,返回读取到的字符(以 int 类型返回,以便区分 EOF)。
  • 如果到达文件末尾或发生错误,返回 EOF(通常定义为 -1)。

5.1.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 以读取模式('r')打开文件 "intput.txt"
    FILE *file = fopen("./path/files/input1.txt", "r"); // 打开文件以供读取

    if (file != NULL)
    {
        int ch; // 用于存储读取的字符

        puts("使用 fgetc 循环读取的文件内容:"); // puts 自带换行效果

        // 使用 fgetc 逐字符读取文件
        while ((ch = fgetc(file)) != EOF)
        {
            // printf("%c", ch); // 将字符显示在屏幕上
            putchar(ch);
        }

        fclose(file); // 关闭文件
    }
    else
    {
        printf("Error opening the file.\n"); // 如果文件打开失败,输出错误信息
    }

    return 0;
}

input1.txt 内容如下所示:

输出结果如下所示:

5.2 fgets() 函数

5.2.1 功能说明

fgets() 函数的主要功能是从指定的文件流中读取一行文本,并将其存储到指定的缓冲区中。如果读取成功,该函数返回指向缓冲区的指针;如果到达文件末尾或发生错误,返回 NULL。

5.2.2 函数原型

cpp 复制代码
#include <stdio.h>
char *fgets(char *str, int n, FILE *stream);

参数:

  • str :一个指向字符数组的指针,表示用于存储读取到的字符串的缓冲区。
  • n :一个整数,表示缓冲区的最大长度。fgets 最多读取 n-1 个字符,并在末尾添加一个空字符 '\0'。
  • stream :一个指向 FILE 类型的指针,表示要读取的文件流。这个指针通常是通过 fopen() 函数获得的。

返回值:

  • 如果读取成功,返回指向缓冲区的指针(即 str)。
  • 如果到达文件末尾或发生错误,返回 NULL。

5.2.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 以读取模式('r')打开文件 "intput.txt"
    FILE *file = fopen("./path/files/input2.txt", "r"); // 打开文件以供读取

    if (file != NULL)
    {
        char buffer[1000]; // 用于存储读取的字符串

        // 使用 fgets 逐行读取文件
        while (fgets(buffer, sizeof(buffer), file) != NULL)
        {
            // printf("%s", buffer); // 将读取的字符串显示在屏幕上
            puts(buffer);
        }

        fclose(file); // 关闭文件
    }
    else
    {
        printf("Error opening the file.\n"); // 如果文件打开失败,输出错误信息
    }

    return 0;
}

input2.txt 内容如下所示:

输出结果如下所示:

5.3 fscanf 函数

5.2.1 功能说明

fscanf() 函数的主要功能是从指定的文件流中读取格式化的输入,并将数据存储到指定的变量中。它类似于 scanf() 函数,但作用于文件流而不是标准输入。fscanf() 使用空白字符(空格、制表符、换行符等)分隔内容,并将其赋值给不同的变量。

5.2.2 函数原型

cpp 复制代码
#include <stdio.h>
int fscanf(FILE *stream, const char *format, ...);

参数:

  • stream :一个指向 FILE 类型的指针,表示要读取的文件流。这个指针通常是通过 fopen() 函数获得的。
  • format:一个指向以 null 结尾的字符串的指针,表示在··在·格式化字符串。格式化字符串可以包含普通字符和格式化说明符(如 %d、%s、%f 等),与 scanf 类似。
  • ...:可变参数列表,根据格式化字符串中的说明符提供相应的指针,与 scanf 类似。

返回值:

  • 如果读取成功,返回成功读取并赋值的项数。
  • 如果到达文件末尾或发生错误,返回 EOF。

5.2.3 案例演示

cpp 复制代码
#include <stdio.h>

int main()
{
    // 以读取模式('r')打开文件 "input3.txt"
    FILE *file = fopen("./path/files/input3.txt", "r"); // 打开文件以供读取

    if (file != NULL)
    {
        // 定义变量用于存储读取的数据
        char msg1[100], msg2[100], msg3[100]; // 用于存储三个字符串
        int num;                              // 用于存储一个整数

        // 使用 fscanf 从文件中读取格式化的数据
        fscanf(file, "%s %s %s %d", msg1, msg2, msg3, &num);

        // 将读取的数据输出到控制台
        printf("%s\n", msg1); // 输出第一个字符串
        printf("%s\n", msg2); // 输出第二个字符串
        printf("%s\n", msg3); // 输出第三个字符串
        printf("%d\n", num);  // 输出整数

        // 关闭文件
        fclose(file);
    }
    else
    {
        // 如果文件打开失败,输出错误信息
        printf("打开文件时出现错误。\n");
    }

    return 0;
}

input3.txt 内容如下所示:

输出结果如下所示:

相关推荐
大小胖虎6 个月前
专业课笔记——(第十二章:文件的读写)
c语言·笔记·字符串·文件·文件存储·文件的读写