C语言文件处理



C语言文件处理

C语言中的文件处理是指使用C语言函数处理文件操作的过程,例如创建、打开、写入数据、读取数据、重命名和删除。借助这些函数,我们可以在程序中执行文件操作,以便在文件中存储和检索数据。

C语言中文件处理的必要性

如果我们使用C程序执行输入和输出操作,则数据仅在程序运行期间存在,当程序终止时,我们无法再次使用该数据。文件处理需要处理存储在外部存储器中的文件,即从计算机的外部存储器存储和访问信息。您可以使用文件处理永久保存数据。

文件的类型

文件表示一系列字节。文件有两种类型:文本文件二进制文件

  1. 文本文件 - 文本文件以ASCII字符的形式包含数据,通常用于存储字符流。文本文件中的每一行以换行符("\n")结尾,通常具有".txt"扩展名。
  2. 二进制文件 - 二进制文件以原始位(0和1)的形式包含数据。不同的应用程序程序有不同的表示位和字节的方法,并使用不同的文件格式。图像文件(.png,.jpg),可执行文件(.exe,.com)等是二进制文件的示例。

文件指针 (File*)

在处理文件处理时,您需要一个文件指针来存储fopen()函数返回的FILE结构的引用。所有文件处理操作都需要文件指针。

fopen()函数 返回FILE类型的指针。FILEstdio.h中预定义的结构体类型,包含文件描述符、大小和位置等属性。

typedef struct {
   int fd;			/* File descriptor */
   unsigned char *buf;	/* Buffer */
   size_t size;		/* Size of the file */
   size_t pos;		/* Current position in the file */
} FILE;

声明文件指针 (FILE*)

以下是声明文件指针的语法:

FILE* file_pointer;

打开(创建)文件

必须打开文件才能执行任何操作。fopen()函数用于创建新文件或打开现有文件。您需要指定要打开的模式。下面解释了各种文件打开模式,在创建/打开文件时可以使用其中任何一种。

fopen()函数返回一个FILE指针,该指针将用于其他操作,例如读取、写入和关闭文件。

语法

以下是打开文件的语法:

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

这里,filename是要打开的文件的名称,mode定义文件的打开模式。

文件打开模式

文件访问模式默认以文本或ASCII模式打开文件。如果要处理二进制文件,则应使用以下访问模式,而不是上述模式

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

文件可以以多种模式打开。以下是不同的文件打开模式:

模式 描述
r 以读取目的打开现有的文本文件。
w 打开文本文件以进行写入。如果文件不存在,则创建一个新文件。在此,您的程序将从文件开头开始写入内容。
a 以追加模式打开文本文件以进行写入。如果文件不存在,则创建一个新文件。在此,您的程序将开始将内容追加到现有文件内容中。
r+ 打开文本文件以进行读写。
w+
a+ 打开文本文件以进行读写。如果文件不存在,则创建文件。读取将从开头开始,但只能追加写入。

创建文件的示例

在以下示例中,我们正在创建一个新文件。创建新文件的文件模式将为“w”(写入模式)。

#include <stdio.h>

int main() {
  FILE * file;

  // Creating a file
  file = fopen("file1.txt", "w");

  // Checking whether file is 
  // created or not
  if (file == NULL) {
    printf("Error in creating file");
    return 1;
  }
  printf("File created.");

  return 0;
}

输出

File created.

打开文件的示例

在以下示例中,我们正在打开一个现有文件。打开现有文件的文件模式将为“r”(只读)。您也可以使用上面解释的其他文件打开模式选项。

注意:必须存在要打开的文件。

#include <stdio.h>

int main() {
  FILE * file;

  // Opening a file
  file = fopen("file1.txt", "r");

  // Checking whether file is 
  // opened or not 
  if (file == NULL) {
    printf("Error in opening file");
    return 1;
  }
  printf("File opened.");

  return 0;
}

输出

File opened.

关闭文件

每个文件在对其执行操作后都必须关闭。 fclose()函数 关闭打开的文件。

语法

以下是fclose()函数的语法:

int fclose(FILE *fp);

fclose()函数在成功时返回零,如果关闭文件时出错则返回EOF。

fclose()函数实际上会将缓冲区中仍挂起的所有数据刷新到文件,关闭文件并释放用于文件的所有内存。EOF是头文件stdio.h中定义的常量。

关闭文件的示例

在以下示例中,我们正在关闭打开的文件:

#include <stdio.h>

int main() {
  FILE * file;

  // Opening a file
  file = fopen("file1.txt", "w");

  // Checking whether file is 
  // opened or not 
  if (file == NULL) {
    printf("Error in opening file");
    return 1;
  }
  printf("File opened.");

  // Closing the file
  fclose(file);
  printf("\nFile closed.");

  return 0;
}

输出

File opened.
File closed.

写入文本文件

提供了以下库函数以将数据写入以可写模式打开的文件:

  • fputc():将单个字符写入文件。
  • fputs():将字符串写入文件。
  • fprintf():将格式化字符串(数据)写入文件。

将单个字符写入文件

fputc()函数 是一个非格式化函数,它将参数“c”的单个字符值写入“fp”引用的输出流。

int fputc(int c, FILE *fp);

示例

在以下代码中,给定字符数组中的一个字符被写入以“w”模式打开的文件中

#include <stdio.h>

int main() {

   FILE *fp;
   char * string = "C Programming tutorial from TutorialsPoint";
   int i;
   char ch;

   fp = fopen("file1.txt", "w");

   for (i = 0; i < strlen(string); i++) {
      ch = string[i];
      if (ch == EOF)
         break;
      fputc(ch, fp);
   }
   printf ("\n");
   fclose(fp);
   
   return 0;
}

输出

After executing the program, "file1.txt" will be created in the current folder and the string is written to it.

将字符串写入文件

fputs()函数 将字符串“s”写入“fp”引用的输出流。如果成功,它将返回非负值,否则在发生任何错误时返回EOF。

int fputs(const char *s, FILE *fp);

示例

以下程序将给定二维字符数组中的字符串写入文件:

#include <stdio.h>

int main() {

   FILE *fp;
   char *sub[] = {"C Programming Tutorial\n", "C++ Tutorial\n", "Python Tutorial\n", "Java Tutorial\n"};
   fp = fopen("file2.txt", "w");

   for (int i = 0; i < 4; i++) {
      fputs(sub[i], fp);
   }

   fclose(fp);
   
   return 0;
}

输出

当程序运行时,将在当前文件夹中创建一个名为“file2.txt”的文件,并保存以下行:

C Programming Tutorial
C++ Tutorial
Python Tutorial
Java Tutorial

将格式化字符串写入文件

fprintf()函数 将格式化的数据流发送到FILE指针表示的磁盘文件。

int fprintf(FILE *stream, const char *format [, argument, ...])

示例

在以下程序中,我们有一个名为“employee”的结构体类型数组。该结构体具有字符串、整数和浮点数元素。使用fprintf()函数,数据被写入文件。

#include <stdio.h>

struct employee {
   int age;
   float percent;
   char *name;
};

int main() {

   FILE *fp;
   struct employee emp[] = {
      {25, 65.5, "Ravi"}, 
      {21, 75.5, "Roshan"}, 
      {24, 60.5, "Reena"}
   };

   char *string;
   fp = fopen("file3.txt", "w");

   for (int i = 0; i < 3; i++) {
      fprintf(fp, "%d %f %s\n", emp[i].age, emp[i].percent, emp[i].name);
   }
   fclose(fp);
   
   return 0;
}

输出

When the above program is executed, a text file is created with the name "file3.txt" that stores the employee data from the struct array.

从文本文件读取

以下库函数用于读取以读取模式打开的文件中的数据:

  • fgetc():从文件读取单个字符。
  • fgets():从文件读取字符串。
  • fscanf():从文件读取格式化字符串。

从文件读取单个字符

fgetc() 函数从“fp”引用的输入文件中读取一个字符。返回值是读取的字符,如果发生任何错误,则返回 EOF。

int fgetc(FILE * fp);

示例

以下示例以逐字符的方式读取给定文件,直到到达文件末尾。

#include <stdio.h>

int main(){

   FILE *fp ;
   char ch ;
   fp = fopen ("file1.txt", "r");

   while(1) {
      ch = fgetc (fp);
      if (ch == EOF)
         break;
      printf ("%c", ch);
   }
   printf ("\n");
   fclose (fp);
}

输出

运行代码并检查其输出:

C Programming tutorial from TutorialsPoint

从文件读取字符串

fgets() 函数从“fp”引用的输入流中读取最多“n - 1”个字符。它将读取的字符串复制到缓冲区“buf”中,并在字符串末尾附加一个空字符以终止字符串。

示例

以下程序读取给定文件中的每一行,直到检测到文件末尾:

# include <stdio.h>

int main() {

   FILE *fp;
   char *string;
   fp = fopen ("file2.txt", "r");

   while (!feof(fp)) {
      fgets(string, 256, fp);
      printf ("%s", string) ;
   }
   fclose (fp);
}

输出

运行代码并检查其输出:

C Programming Tutorial
C++ Tutorial
Python Tutorial
Java Tutorial

从文件读取格式化字符串

C 编程语言中的fscanf() 函数用于从文件读取格式化输入。

int fscanf(FILE *stream, const char *format, ...)

示例

在以下程序中,我们使用fscanf()函数读取不同类型变量中的格式化数据。通常使用格式说明符来指示字段类型(%d、%f、%s 等)。

#include <stdio.h>

int main() {

   FILE *fp;
   char *s;
   int i, a;  
   float p;

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

   if (fp == NULL) {
      puts ("Cannot open file"); return 0;
   }

   while (fscanf(fp, "%d %f %s", &a, &p, s) != EOF)
   printf ("Name: %s Age: %d Percent: %f\n", s, a, p);
   fclose(fp);

   return 0;
}

输出

执行上述程序时,它会打开文本文件“file3.txt”并在屏幕上打印其内容。运行代码后,您将获得如下输出:

Name: Ravi Age: 25 Percent: 65.500000
Name: Roshan Age: 21 Percent: 75.500000
Name: Reena Age: 24 Percent: 60.500000

文件处理二进制读写函数

对于二进制文件,读写操作以二进制形式完成。您需要在访问模式中包含字符“b”(“wb”用于写入二进制文件,“rb”用于读取二进制文件)。

有两个函数可用于二进制输入和输出:fread()函数和fwrite()函数。这两个函数都应用于读取或写入内存块,通常是数组或结构。

写入二进制文件

fwrite() 函数将指定大小的字节块从缓冲区写入以二进制写入模式打开的文件。以下是使用此函数的原型

fwrite(*buffer, size, no, FILE);

示例

在以下程序中,已声明了一个名为“employee”的结构体类型的数组。我们使用fwrite()函数写入一个字节块,相当于一个employee数据的尺寸,写入以“wb”模式打开的文件中。

#include <stdio.h>

struct employee {
   int age;
   float percent;
   char name[10];
};

int main() {

   FILE *fp;
   struct employee e[] = {
      {25, 65.5, "Ravi"}, 
      {21, 75.5, "Roshan"}, 
      {24, 60.5, "Reena"}
   };

   char *string;

   fp = fopen("file4.dat", "wb");
   for (int i = 0; i < 3; i++) {
      fwrite(&e[i], sizeof (struct employee), 1, fp);
   }

   fclose(fp);
   
   return 0;
}

输出

When the above program is run, the given file will be created in the current folder. It will not show the actual data, because the file is in binary mode.

从二进制文件读取

fread() 函数从以二进制读取模式打开的文件中读取指定大小的字节块到指定大小的缓冲区。以下是使用此函数的原型

fread(*buffer, size, no, FILE);

示例

在以下程序中,已声明了一个名为“employee”的结构体类型的数组。我们使用fread()函数读取一个字节块,相当于一个employee数据的尺寸,读取以“rb”模式打开的文件中。

#include <stdio.h>

struct employee {
   int age;
   float percent;
   char name[10];
};

int main() {

   FILE *fp;
   struct employee e;

   fp = fopen ("file4.dat", "rb");

   if (fp == NULL) {
      puts ("Cannot open file"); 
      return 0;
   }

   while (fread (&e, sizeof (struct employee), 1, fp) == 1)
   printf ("Name: %s Age: %d Percent: %f\n", e.name, e.age, e.percent);

   fclose(fp);
   
   return 0;
}

输出

执行上述程序时,它会打开文件“file4.dat”并在屏幕上打印其内容。运行代码后,您将获得如下输出:

Name: Ravi Age: 25 Percent: 65.500000
Name: Roshan Age: 21 Percent: 75.500000
Name: Reena Age: 24 Percent: 60.500000

重命名文件

rename() 函数用于将现有文件从旧文件名重命名为新文件名。

语法

以下是重命名文件的语法:

int rename(const char *old_filename, const char *new_filename)

示例

#include <stdio.h>

int main() {
  // old and new file names
  char * file_name1 = "file1.txt";
  char * file_name2 = "file2.txt";

  // Renaming old file name to new one
  if (rename(file_name1, file_name2) == 0) {
    printf("File renamed successfully.\n");
  } else {
    perror("There is an error.");
  }

  return 0;
}

输出

如果存在文件(file1.txt),则以下将是输出:

Name: Ravi Age: 25 Percent: 65.500000
Name: Roshan Age: 21 Percent: 75.500000
Name: Reena Age: 24 Percent: 60.500000
广告