C 文件 I/O:创建、打开、读取、写入和关闭文件

⚡ 智能摘要

C 语言中的文件处理通过 stdio 库将持久数据存储在磁盘上,该库使用 fopen 打开文件,使用 fputc、fputs 或 fprintf 写入文件,使用 fgetc、fgets 或 fscanf 读取文件,并使用 fclose 关闭文件。

  • 📁 文件模式: 传递给 fopen 的模式字符串(r、w、a、r+、w+ 或 a+)决定文件是被读取、覆盖还是追加。
  • ✍️ 写入数据: fputc 向文件指针写入一个字符,fputs 向文件指针写入一个字符串,fprintf 向文件指针写入格式化文本。
  • ???? 读取数据: fgetc 读取一个字符,fgets 将一行读取到缓冲区中,fscanf 解析文件中的格式化标记。
  • 🔒 正在关闭文件: fclose 会刷新缓冲数据并释放文件,成功时返回 0,失败时返回 EOF。
  • 🔁 交互式 I/O: getc 和 putc 一次处理一个字符,将输入直接移入文件,然后再移出。
  • 🤖 人工智能辅助: GitHub Copilot 和 AI 助手会生成 fopen、fprintf 和 fgets 例程,并标记缺失的 NULL 检查或未关闭的文件。

C 文件输入/输出

C 文件管理

文件可以用来存储大量持久性数据。像许多其他语言一样,C 语言提供了以下文件管理功能。 功能,

  1. 创建文件
  2. 打开文件
  3. 读取文件
  4. 写入文件
  5. 关闭文件

以下是“C”中最重要的文件管理函数,

function 目的
开张() 创建文件或打开现有文件
关闭函数 关闭文件
fprintf() 将数据块写入文件
fscanf()函数 从文件读取块数据
获取函数 从文件中读取单个字符
放出() 将单个字符写入文件
获取 () 从文件读取一个整数
putw() 复制代码 将整数写入文件
查找 () 将文件指针的位置设置为指定位置
ftell() 返回文件指针的当前位置
倒回 () 将文件指针设置在文件开头

如何创建文件

每当你想要操作一个文件时,第一步就是创建一个文件。文件只不过是内存中存储数据的空间。

要在“C”程序中创建文件,请使用以下语法,

FILE *fp;
fp = fopen ("file_name", "mode");

在上面的语法中,文件是在标准库中定义的数据结构。

fopen 是一个用于打开文件的标准函数。

  • 如果系统中不存在该文件,则创建该文件然后打开它。
  • 如果系统上已存在该文件,则使用此功能直接打开该文件。

fp 是一个文件 指针 它指向类型文件。

无论何时打开或创建文件,您都必须指定要对文件执行的操作。在“C”语言编程中,可以创建或打开文件以进行读取/写入。模式用于指定是否要为以下任何目的打开文件。以下是“C”语言编程中可用于处理文件的不同类型的模式。

文件模式 描述
r 打开文件进行读取。如果文件处于读取模式,则如果文件已存在于系统中,则不会删除任何数据。
w 打开文件进行写入。如果文件处于写入模式,则如果文件根本不存在,则创建一个新文件。如果文件已存在于系统中,则文件内的所有数据都将被截断,并打开文件进行写入。
a 以追加模式打开文件。如果文件处于追加模式,则文件会被打开,但文件内容不会改变。
r+ 从一开始就开放以供读写
w+ 打开以进行读写,覆盖文件
a+ 打开以进行读写,附加到文件

在给定的语法中,文件名和模式被指定为: 字符串 因此,它们必须始终用双引号括起来。

例如:

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("data.txt", "w");
}

输出:

文件在您保存代码的同一文件夹中创建。

在 C 程序输出中创建文件

您可以指定要创建文件的路径

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("D://data.txt", "w");
}

在 C 语言中创建指定路径的文件

如何关闭文件

当文件操作结束时,应始终关闭文件。这意味着文件的内容和链接已终止。这可防止文件意外损坏。

C 语言提供了 fclose 函数来执行文件关闭操作。fclose 的语法如下:

fclose (file_pointer);

例如:

FILE *fp;
fp  = fopen ("data.txt", "r");
fclose (fp);

fclose 函数接受一个文件指针作为参数。它使用 fclose 函数关闭与该文件指针关联的文件。如果关闭成功,则返回 0;如果在关闭文件时发生错误,则返回 EOF(文件末尾)。

关闭文件后,同一个文件指针还可以用于其他文件。

在“C”编程中,程序终止时文件会自动关闭。通过编写 fclose 函数手动关闭文件是一种很好的编程习惯。

写入文件

在 C 语言中,当写入文件时,必须明确添加换行符“\n”。

stdio 库提供了写入文件所需的函数:

  • fputc(char, file_pointer): 将一个字符写入 file_pointer 指向的文件。
  • fputs(str, file_pointer): 将字符串写入 file_pointer 指向的文件。
  • fprintf(file_pointer, str, variable_lists): 它将一个字符串打印到 file_pointer 指向的文件。该字符串可以选择性地包含格式说明符和变量列表 variable_lists。

下面的程序显示如何执行写入文件的操作:

fputc() 函数:

#include <stdio.h>
int main() {
        int i;
        FILE * fptr;
        char fn[50];
        char str[] = "Guru99 Rocks\n";
        fptr = fopen("fputc_test.txt", "w"); // "w" defines "writing mode"
        for (i = 0; str[i] != '\n'; i++) {
            /* write to file using fputc() function */
            fputc(str[i], fptr);
        }
        fclose(fptr);
        return 0;
    }

输出:

C语言中fputc()函数的输出

上述程序会将单个字符写入 fputc_test.txt 文件,直到遇到换行符“\n”为止,这表示句子已成功写入。其过程是将数组中的每个字符写入文件。

fputc_test.txt 文件内容以 C 语言编写

  1. 在上面的程序中,我们以写入模式创建并打开了一个名为 fputc_test.txt 的文件,并声明将写入文件的字符串。
  2. 我们使用 for 循环逐个字符地执行写入操作,并将每个字符放入文件中,直到遇到“\n”字符,然后使用 fclose 函数关闭文件。

fputs() 函数:

#include <stdio.h>
int main() {
        FILE * fp;
        fp = fopen("fputs_test.txt", "w+");
        fputs("This is Guru99 Tutorial on fputs,", fp);
        fputs("We don't need to use for loop\n", fp);
        fputs("Easier than fputc function\n", fp);
        fclose(fp);
        return (0);
    }

输出:

C语言中fputs()函数的输出

C语言中的fputs_test.txt文件内容

  1. 在上面的程序中,我们以写入模式创建并打开了一个名为 fputs_test.txt 的文件。
  2. 我们使用 fputs() 函数执行写入操作,写入三个不同的字符串。
  3. 然后使用 fclose 函数关闭文件。

fprintf()函数:

#include <stdio.h>
    int main() {
        FILE *fptr;
        fptr = fopen("fprintf_test.txt", "w"); // "w" defines "writing mode"
        /* write to file */
        fprintf(fptr, "Learning C with Guru99\n");
        fclose(fptr);
        return 0;
    }

输出:

C 语言中 fprintf() 函数的输出

fprintf_test.txt 文件内容(C语言)

  1. 在上面的程序中,我们以写入模式创建并打开了一个名为 fprintf_test.txt 的文件。
  2. 使用 fprintf() 函数通过写入字符串执行写入操作后,使用 fclose 函数关闭文件。

从文件读取数据

有三种不同的函数专用于从文件读取数据

  • fgetc(file_pointer): 此函数返回文件指针指向的文件中的下一个字符。当到达文件末尾时,返回 EOF(文件结束符)。
  • fgets(buffer, n, file_pointer): 它从文件中读取 n-1 个字符,并将字符串存储在缓冲区中,并在最后一个字符后附加 NULL 字符 '\0'。
  • fscanf(文件指针, 转换说明符, 变量地址):用于解析和分析数据。它从文件中读取字符,并使用转换说明符将输入分配给变量指针列表 variable_addresses。请注意,与 scanf 一样,fscanf 在遇到空格或换行符时会停止读取字符串。

以下程序演示分别使用 fgets()、fscanf() 和 fgetc() 函数读取 fputs_test.txt 文件:

#include <stdio.h>
int main() {
        FILE * file_pointer;
        char buffer[30], c;

        file_pointer = fopen("fprintf_test.txt", "r");
        printf("----read a line----\n");
        fgets(buffer, 50, file_pointer);
        printf("%s\n", buffer);

        printf("----read and parse data----\n");
        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        char str1[10], str2[2], str3[20], str4[2];
        fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
        printf("Read String1 |%s|\n", str1);
        printf("Read String2 |%s|\n", str2);
        printf("Read String3 |%s|\n", str3);
        printf("Read String4 |%s|\n", str4);

        printf("----read the entire file----\n");

        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        while ((c = getc(file_pointer)) != EOF) printf("%c", c);

        fclose(file_pointer);
        return 0;
    }

结果:

----read a line----
Learning C with Guru99

----read and parse data----
Read String1 |Learning|
Read String2 |C|
Read String3 |with|
Read String4 |Guru99|
----read the entire file----
Learning C with Guru99

C 语言输出中从文件中读取数据

  1. 在上面的程序中,我们打开了名为“fprintf_test.txt”的文件,该文件之前使用fprintf()函数写入,内容为“Learning C with Guru99”字符串。我们使用fgets()函数读取它,该函数逐行读取,缓冲区大小必须足以处理整行。
  2. 我们重新打开文件,将文件指针重置为指向文件开头。创建多个字符串变量来分别处理每个单词。打印这些变量以查看它们的内容。fscanf() 函数主要用于执行检查。tract 并解析文件中的数据。
  3. 重新打开文件以重置指针文件以指向文件的开头。使用 getc() 函数从文件中逐个字符读取数据并打印,直到遇到 EOF 语句
  4. 在使用不同变体执行读取操作文件后,我们再次使用 fclose 函数关闭文件。

使用 getc 和 putc 进行交互式文件读写

这些是最简单的文件操作。getc 代表获取字符,putc 代表放置字符。这两个函数每次只用于处理一个字符。

以下程序演示了 C 编程中的文件处理功能:

#include <stdio.h>
int main() {
        FILE * fp;
        char c;
        printf("File Handling\n");
        //open a file
        fp = fopen("demo.txt", "w");
        //writing operation
        while ((c = getchar()) != EOF) {
            putc(c, fp);
        }
        //close file
        fclose(fp);
        printf("Data Entered:\n");
        //reading
        fp = fopen("demo.txt", "r");
        while ((c = getc(fp)) != EOF) {
            printf("%c", c);
        }
        fclose(fp);
        return 0;
    }

输出:

C 语言交互式文件读写输出

C 语言中的 getc 和 putc 文件处理输出

  1. 在上面的程序中,我们以写入模式创建并打开了一个名为 demo 的文件。
  2. 执行写入操作后,使用 fclose 函数关闭文件。
  3. 我们再次打开了一个文件,该文件现在以读取模式包含数据。while 循环将执行,直到找到 eof。一旦找到文件末尾,操作将终止,并使用 printf 函数显示数据。
  4. 执行读取操作后,再次使用 fclose 函数关闭文件。

常见问题

文本模式会将换行符转换为操作系统默认的格式,而二进制模式(使用“rb”或“wb”命令打开)则会按原样写入字节。对于图像、音频或任何需要保留精确字节布局的数据,请使用二进制模式。

当文件无法打开时(例如文件缺失、权限不足或磁盘已满),fopen 函数会返回 NULL。在进行读写操作之前,务必检查返回的指针是否为 NULL,否则程序会使用无效指针,通常会导致程序崩溃。

写入模式“w”会截断现有文件,在写入之前擦除其内容,并在文件不存在时创建该文件。追加模式“a”会保留现有数据,并在末尾添加新内容,因此不会丢失任何已存储的数据。

fseek 将文件指针移动到从 SEEK_SET、SEEK_CUR 或 SEEK_END 开始计算的字节偏移量。ftell 返回指针的当前字节位置,而 rewind 则将其返回到文件开头。它们共同实现了随机访问,而非顺序读取。

fgets 读取了一整行,停止ping fscanf 会在换行符处或 n-1 个字符后读取数据,因此它会遵守缓冲区大小的限制。fscanf 读取的是格式化的、以空格分隔的标记,因此可能会导致短数组溢出。如果需要安全地读取整行数据,fgets 是更好的选择。

EOF 是一个常量,通常为 -1,用于标记文件末尾。诸如 getc、fgetc 和 fscanf 之类的读取函数在文件没有剩余数据时会返回 EOF,这就是为什么循环会将它们的结果与 EOF 进行比较以停止读取的原因。

是的。AI 代码助手可以根据纯文本提示生成 fopen、fprintf 和 fgets 函数,解释每种文件模式,并找出诸如缺少空值检查或文件未关闭之类的错误。在信任 AI 生成的代码之前,务必编译并测试它。

GitHub 副驾驶 它会根据简短的注释或函数名生成完整的 C 文件处理代码,并建议使用 fopen、fputs 和 fscanf 代码块。它通常还会添加匹配的 fclose 调用和错误检查,但您仍然应该检查生成的逻辑。

总结一下这篇文章: