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

目录

1 文件的存储形式

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

2.1 功能描述

2.2 函数原型

2.3 文件打开方式(模式)

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

3.1 功能描述

3.2 函数原型

4 常见的文件写入方式

4.1 fputc() 函数

4.1.1 功能描述

4.1.2 函数原型

4.1.3 案例演示

4.2 fputs() 函数

4.2.1 功能说明

4.2.2 函数原型

4.2.3 案例演示

4.3 fprintf() 函数

4.3.1 功能说明

4.3.2 函数原型

4.3.3 案例演示

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

5 常见的文件写入方式

5.1 fgetc() 函数

5.1.1 功能说明

5.1.2 函数原型

5.1.3 案例演示

5.2 fgets() 函数

5.2.1 功能说明

5.2.2 函数原型

5.2.3 案例演示

5.3 fscanf 函数

5.2.1 功能说明

5.2.2 函数原型

5.2.3 案例演示


1 文件的存储形式

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

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

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

2.1 功能描述

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

2.2 函数原型

#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+,允许读写二进制文件。

补充说明:

  • 文件指针位置:在某些模式下,文件指针的位置是固定的。例如,在 a 和 a+ 模式下,文件指针默认位于文件末尾,但在读取时可以从文件开头开始。
  • 文件创建:在 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 函数原型

#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 函数原型

#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 案例演示

#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 函数原型

#include <stdio.h>
int fputs(const char *str, FILE *stream);

参数:

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

返回值:

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

4.2.3 案例演示

#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 函数原型

#include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);

参数:

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

返回值:

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

4.3.3 案例演示

#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 文件写入——综合案例演示

#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 函数原型

#include <stdio.h>
int fgetc(FILE *stream);

参数:

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

返回值:

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

5.1.3 案例演示

#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 函数原型

#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 案例演示

#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 函数原型

#include <stdio.h>
int fscanf(FILE *stream, const char *format, ...);

参数:

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

返回值:

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

5.2.3 案例演示

#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 内容如下所示:

        输出结果如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thanks_ks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值