C 语言中的文件处理


2021年8月23日, Learn eTutorial
2513

在本教程中,您将通过示例掌握有关 C 语言文件和文件操作的所有知识。您将了解什么是文件、如何打开和关闭文件,以及通过 C 编程读写文件的一些基本方法。

什么是文件?

文件是具有特定名称的字节集合。确切地说,文件是系统存储上的一个命名位置,用于存储相关数据以供将来使用。数据可以是任何东西,如简单的文本文件、视频或音频文件,或任何复杂的可执行程序。我们使用文件系统在硬盘等非易失性内存中实现持久存储。

为什么在 C 语言中使用文件?

当我们编译和运行一个程序时,我们肯定会得到一个输出。一旦我们退出程序,所有的输入和输出都会从内存中被清除。I/O 函数帮助我们将这些数据以文件的形式存储在硬盘或可移动磁盘上,从而确保数据的永久存储。另一个原因是,在处理大量数据时,文件很容易操作,因为将大量数据输入程序根本不被认为是一种好的做法。存储在文件中的数据可以使用文件命令进行访问。此外,文件在计算机之间传输也很方便。

文件类型

文件分为两种类型

THE FLOWCHART OF IF STATEMENT
  1. 二进制文件是包含非文本值(如图像、音频等)的文件。通常,二进制文件包含以零和一形式表示的对象。二进制文件是您计算机中的 .bin 文件,它们对用户不友好,因此不可读,但提供了高安全性。
  2. 文本文件是包含构造成行的文本值的文件。简而言之,一个文本文件包含多行文本值。每行都以一个称为行尾(End of Line)的特殊字符结束,并且通常以 .txt 扩展名保存。

C 语言中的文件操作

下面列出了在处理文件时需要执行的 4 种基本操作。它们按处理顺序列出。

  1. 创建一个新文件
  2. 打开一个现有文件
  3. 读取或写入操作
  4. 关闭一个已打开的文件

文件处理流程图
 

THE FLOWCHART OF IF STATEMENT

如何打开文件?

由于文件存储在磁盘上,我们需要通过声明一个文件类型的指针在文件和程序之间建立链接,如下所示。


FILE *fptr; 
 

然后我们可以先打开一个文件以便读取或写入它。fopen() 函数通常用于完成这项工作。它告诉操作系统打开文件名以及打开它的原因。如果操作系统成功做到这一点,它会将文件第一个字节的地址作为指向文件结构的指针发送回来。该函数的原型是


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

其中

  • filename 给出要打开的文件的名称,
  • mode 表示文件的打开模式(r、w、a - 读取、写入、追加)

假设我们想以读取目的打开一个名为“Data.dat”的文件。在这种情况下,参数将是


FILE *fptr; 
fptr= fopen("DATA.dat", "r");
 

这里的“r”表示文件将是只读的。显然,参数的第二个参数决定了文件的属性。
这是显示不同文件打开模式的表格。
 

模式 含义 描述
r 读取 打开一个文本文件进行读取。如果文件不存在,fopen() 返回 Null。
w 写入 以只写模式打开文本文件以进行覆盖。如果文件不存在,则创建一个文件。
a 追加 在文件末尾追加内容而不截断现有内容。如果文件不存在,则创建一个文件。
r+ 读写 打开文件进行读写
w+ 读写 以写读模式打开文件
a+ 追加读写 以追加模式打开文件进行读写。
rb 二进制读取 打开一个二进制文件进行读取
wb 二进制写入 打开一个二进制文件进行写入。
ab 二进制追加 打开一个二进制文件以在文件末尾追加
rb+ 二进制读写 打开一个二进制文件进行读写
wb+ 二进制读写 打开一个二进制文件进行写读
ab+ 二进制追加读写 以读写模式打开一个二进制文件进行追加

如何关闭文件?

在读取或写入后,我们必须关闭它,fclose() 函数负责这项工作。该函数的原型在 <stdio.h> 头文件中声明。


fclose(fp);
 

该函数使用 fp,一个指向 FILE 结构的指针,与 fopen 函数完全相似。当我们将数据写入文件时,它首先存储在缓冲区中。当缓冲区变满或编译器遇到 fclose() 函数时,数据才真正写入磁盘。

如何从文件中读取和写入?

有几个函数可用于从文件中读取数据和向文件中写入数据。下面将这些函数列表化以便于理解。

序号 函数 描述
1 fprintf() 将数据写入文件
2 fscanf() 从文件中读取数据
3 fputc() 将一个字符写入文件
4 fgetc() 从文件中读取一个字符
5 fseek() 将文件指针设置到特定位置
6 fputs() 将一个字符串写入文件
7 fgets() 从文件中读取一个字符串
8 ftell() 返回当前位置
9 rewind() 将文件指针设置到开头
10 fread() 从二进制文件读取数据
11 fwrite() 向二进制文件写入数据

写入文本文件

要向文本文件写入内容,最简单的是 putc。其原型如下:


putc (int ch, FILE *stream); 
 

这里是一个例子,说明了该函数的应用。


#include <stdio.h>
main()
{
   FILE *fp; 
   char ch; 
   fp= fopen ("FILE.txt", "w");
   while ((ch=getche()) != '\r') 
       putc (ch, fp);
}
 

在这个程序中,getche 会接收单个字符输入并将其存储在变量 ch 中。putc 将使用文件指针 fp 将该字符写入目标文件“FILE.txt”。

File I/O

fputs 是另一个函数,能够一次性将一个字符串写入文件。其语法是


fputs (const char *str,  FILE *stream);
 

从文本文件读取

fgetc 函数是读取文件内数据的最简单工具。该函数的原型是


fgetc(FILE *stream);
 

我们可以使用 'while 循环' 来读取多个字符。


while ((ch= fgetc (fp)) !=EOF) 
   printf ("%c", ch); 
 

就像 'fputs' 一样,有一个名为 'fgets' 的函数。如果输入流引用有 'n' 个字符,那么它将能够读取 (n-1) 个字符。

从文本文件读取的示例

假设我们有一个名为 myfile.txt 的文件,如下所示,其中包含一些数据。

File I/O

让我们编写一个简单的 C 程序,使用 fgetc 来读取该文件。
 


#include<stdio.h>

void main()
{
    FILE *fp;
    char c;

    fp=fopen("myfile.txt","r");

    while((c=fgetc(fp))!=EOF){
    printf("%c",c);
}
fclose(fp);
}

 

该程序输出文件 myfile.txt 中包含的数据,并且在控制台上打印的输出是


This is how we read data in a file using C programming.

二进制 I/O 函数

到目前为止,我们已经讨论了文本文件。但是我们也可以通过 C 编程来读取、写入或编辑二进制文件。在这种情况下,第二个参数是 'rb' 而不是 'r'。同样,'w' 被 'wb' 替换。


fp= fopen ("binary.bin", "rb");
 

在文本文件中,'\n'被视为单个字符,而在二进制文件中它被视为两个连续的字符。此外,我们不能在二进制文件的末尾添加任何“文件结束”字符。

'fread' 和 'fwrite' 是基本函数,主要用于读写这类文件。它们的原型是


size_t fwrite (void *buf,  int size,  int, count,  FILE *fp); 
 

and


size_t fread (void *buf,  int size,  int, count,  FILE *fp);
 
  • Buffer:简称 buf,是一个指针,包含数据将被存储的地址。缓冲区是临时存储数据的内存位置。
  • Size:要读取或写入的每个元素的大小(以字节为单位)
  • Count:要读取或写入的元素数量
  • Stream:指向要从中读取或写入数据的 FILE 对象的指针。

检查下面的程序,它写入结构体
 


#include<stdio.h>
#include<stdlib.h>
struct Book
{
    char Title[20];
    int price;
};

int main()
{
    struct Book B;
    FILE *fp;

    fp=fopen("Book.txt","wb");
    if(fp==NULL)
    {
        printf("Error: Cannot open file");
        exit(1);
    }

    printf("\n Enter the title of the book:");
    gets(B.Title);
    printf("\n Enter the price of the book:");
    fflush(stdin);
    scanf("%d",&B.price);

    fwrite(&B,sizeof(struct Book),1,fp);
    printf("Data is stored in th file successfully in binary format");
    fclose(fp);
    return 0;
}

 

输出


Enter the title of the book:Alchemist

Enter the price of the book:1500

Data is stored in the file successfully in binary format

在上面的程序中,我们创建了一个名为 Book 的结构体,其成员为 Title 和 Price。在 main 函数中,我们声明了一个文件指针 fp,并打开了 Book.txt 文件以写入书的标题和价格。但我们需要以二进制格式存储数据,所以我们使用了 fwrite() 函数。之后,您可以转到文件位置,检查文件内部存储了哪些详细信息。由于详细信息是以二进制格式存储的,您只能读取少量数据。

为了以二进制格式读取数据,您可以使用 fread() 函数,如下面的程序所示。


#include<stdio.h>
#include<stdlib.h>
struct Book
{
    char Title[20];
    int price;
};

int main()
{
    struct Book B;
    FILE *fp;

    fp=fopen("Book.txt","rb");
    if(fp==NULL)
    {
        printf("Error: Cannot open file");
        exit(1);
    }

    fread(&B,sizeof(struct Book),1,fp);
    printf("\nTITLE OF BOOK : %s",B.Title);
    printf("\nPRICE OF BOOK : %d",B.price);
    fclose(fp);

}

 

输出


TITLE OF BOOK : Alchemist
PRICE OF BOOK : 1500