【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)

简介: 【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)

完成后我们再用“ 读 ”模式打开该文件,并在判断非空后使用 fgetc 函数来顺序读取该文件中的内容:

int main()
{
  FILE* p = fopen("test.txt", "r");
  //文件打开模式为“读”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  int ch = 0;
  while ((ch = fgetc(p)) != EOF)
  {
    printf("%c ", ch);
    //顺序读取文件指针pp指向文件内的信息并打印
  }
  fclose(p);
  p = NULL;
  return 0;
}

将程序编译运行起来查看我们 fgetc 函数的读取结果eb36a65b84de4f579c231cb08e5ce14f.png并且我们也可以使用 fputs 函数(区别于 fputc 函数)来实现字符串的顺序写入:

int main()
{
  FILE* p = fopen("test.txt", "w");
  //文件打开模式为“写”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  fputs("The test TXT\n", p);
  //fputc 为写入字符,fouts 为写入字符串
  //只写入字符串内容,不会自动换行,想要换行需手动添加换行转义字符\n
  //并且在写入时,会覆盖原本的内容数据
  fputs("The test TXT", p);
  fclose(p);
  p = NULL;
  return 0;
}

或使用 fgets 函数(区别于 fgetc 函数)来实现字符串的顺序读取:

int main()
{
  FILE* p = fopen("test.txt", "r");
  //文件打开模式为“读”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  char arr[256] = { 0 };
  //定义字符数组用于存放读取到的字符串
  fgets(arr, 256, p);
  //从文件指针p指向文件处,读取最多256个字符,并将数据读取至字符数组arr中
  //该函数为按行读取,读取至换行转义符\n处主动停止并换行
  printf("%s", arr);
  //想要读取两行就需要使用两次fgets函数
  fgets(arr, 256, p);
  printf("%s", arr);
  fclose(p);
  p = NULL;
  return 0;
}

最终目的,就是要结合文件操作将数据保存至本地硬盘中,从而实现优化,于是我们可以使用 fprintf 函数实现将结构体变量的内容保存至本地硬盘之中:

typedef struct Contact
{
  char name[20];
  char sex[5];
  int age;
  char tele[11];
}con;
int main()
{
  FILE* p = fopen("test.txt", "w");
  //文件打开模式为“写”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  con c1 = { "Sherry","女",18,"3478290" };
  fprintf(p, "%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele);
    //按照"%s %s %d %s\n"的格式将数据c1.name, c1.sex, c1.age, c1.tele写入至p所指向的文件内
  fclose(p);
  p = NULL;
  return 0;
}

程序编译运行结束后关闭,这时我们再去本地文件中查看会发现,数据已经成功的保存至本地硬盘中了:

cb9b5b9e6b404350af0341f69cc2fc82.png

并且我们也可以通过 fscanf 函数从本地硬盘文件中读取数据:

typedef struct Contact
{
  char name[20];
  char sex[5];
  int age;
  char tele[11];
}con;
int main()
{
  FILE* p = fopen("test.txt", "r");
  //文件打开模式为“读”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  con c1 = { 0 };
  fscanf(p, "%s %s %d %s", c1.name, c1.sex, &(c1.age), c1.tele);
  //按照"%s %s %d %s"的格式,从p所指向的文件中将数据读取至c1.name, c1.sex, &(c1.age), c1.tele中
  printf("%s %s %d %s\n", c1.name, c1.sex, c1.age, c1.tele);
  fclose(p);
  p = NULL;
  return 0;
}

c666fe053df340c09a99307a93e1153a.png

3. 文件随机读写:

我们很多时候并不是要进行顺序读写,而是进行随机读写(伪随机,指不按照顺序依次进行读写)。为了实现这样的操作,我们就需要使用 fseekftellrewind 三个函数来帮助我们对这样的操作进行实现。

3.1 fseek 函数:

fseek 函数的作用为,根据文件指针的位置和偏移量来定位文件指针。

int fseek(FILE* strname, long int offset, int origin);

1.“ offset”为相对于指针位置的指针偏移量

2.“ origin ”为指针位置,其参数有三种:“ SEEK_CUR ”表示文件指针当前位置;“ SEEK_END ”表示文件末尾的位置;“ SEEK_SET ”表示文件开始位置

int main()
{
  FILE* p = fopen("test.txt", "r+");
  //文件打开模式为“读写”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  char ch = 'a';
  for (ch = 'a'; ch <= 'z'; ch++)
  {
    fputc(ch, p);
    //使用 fputc 函数顺序写入小写字符a~z
  }
  fseek(p, 10, SEEK_SET);
  //使用fseek函数将文件指针从文件开始处(参数SEEK_SET表示文件起始位置)指向偏移量为10处
  //偏移量为正表示向后偏移,为负表示向前偏移
  char output;
  output = fgetc(p);
  //接下来进行读取时,继续向后读取一个字符,即字符k
  printf("%c\n", output);
  fclose(p);
  p = NULL;
  return 0;
}

f977e194454249c7ad2208e455361fb2.png

3.2 ftell 函数:

long int ftell(FILE* strname);
• 1

ftell 函数的作用为,返回文件指针相对于文件起始位置的偏移量。

int main()
{
  FILE* p = fopen("test.txt", "r+");
  //文件打开模式为“读写”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  char ch = 'a';
  for (ch = 'a'; ch <= 'z'; ch++)
  {
    fputc(ch, p);
    //使用 fputc 函数顺序写入小写字符a~z
  }
  fseek(p, -5, SEEK_END);
  //使用fseek函数将文件指针从文件结尾处(参数SEEK_SET表示文件起始位置)指向偏移量为-5处
  //偏移量为正表示向后偏移,为负表示向前偏移
  long back = ftell(p);
  //定义整型变量用于接受并记录指针相对于起始位置的偏移量
  printf("指针相对于起始位置的偏移量为:%ld\n", back);
  fclose(p);
  p = NULL;
  return 0;
}

ea4d50a4b88046389c62f6dc4a6079e8.png

3.3 rewind 函数:

void rewind(FILE* strname);

rewind 函数的作用为,使文件指针位置返回文件的起始位置

int main()
{
  FILE* p = fopen("test.txt", "r+");
  //文件打开模式为“读写”
  if (p == NULL)
  {
    perror("FILE_OPEN");
    return 1;
  }
  char ch = 'a';
  for (ch = 'a'; ch <= 'z'; ch++)
  {
    fputc(ch, p);
    //使用 fputc 函数顺序写入小写字符a~z
  }
  fseek(p, -5, SEEK_END);
  rewind(p);
  //使文件指针回归文件起始位置
  printf("%c\n", fgetc(p));
  //打印验证指针当前位置
  fclose(p);
  p = NULL;
  return 0;
}

76b78845340e49e48df9a8bd047af72b.png

4. 文本文件与二进制文件:

根据数据的组织形式,我们将数据文件称为文本文件二进制文件

二进制文件:在我们的计算机内存中,各种数据都是以二进制码的形式进行存储的,以 二进制码形式进行存储的文件

文本文件:以 ASCII 字符形式进行存储的文件

如果我们想要在外存上以 ASCII 码的形式存储数据,就需要在存储前将数据进行转换。

数据在内存中数据到底是如何让进行存储的呢?

实际上,字符在内存中的存储一律是以 ASCII 码的形式进行存储的,而数值型数据既可以用ASCII 码存储,也可以用二进制形式进行存储。

例如十进制数字 10000 在进行存储时,就可以有两种存储形式:

1.二进制形式:

00000000 00000000 00100111 00010000

2.ASCII码形式:

00110001 00110000 00110000 00110000 000110000

1 0 0 0 0


int main()
{
  int a = 10000;
  FILE* p = fopen("test.txt", "wb");
  //“wb”表示以只写模式打开二进制文件
  if (p == NULL)
  {
    perror("FileOpen");
    return 0;
  }
  fwrite(&a, 4, 1, p);
  //将变量a中的数据,每四个字节存储一次,写入文件指针p所指向的文件
  fclose(p);
  p = NULL;
  return 0;
}

在上面这段代码运行成功后,我们已经成功的将变量 a 中的数据写入到了本地磁盘对应的 txt 文件中了,可是我们发现,当我们尝试打开本地文件查看存储的数据时,里面看起来并不是我们想要的结果:

005629e48a8f486d8ce1182a2936b8b4.png

相关文章
|
存储 编译器 程序员
c语言的文件操作与文件缓冲区
如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。磁盘(硬盘)上的文件是文件。但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从文件功能的角度来分类 的)。就比如说我们电脑中以.txt为后缀的就是文件的一种,他就是数据文件。.exe为后缀的就为程序文件。函数名功能适用范围fgetc字符输入函数所有输入流fputc字符输出函数所有输出流fgets。
569 0
|
人工智能 C语言
|
存储 小程序 C语言
【C语言程序设计——文件】文件操作(头歌实践教学平台习题)【合集】
本文介绍了C语言中的文件操作,分为两个关卡。第1关任务是将键盘输入的字符(以#结束)存入`file1.txt`并显示输出;第2关任务是从键盘输入若干行文本(每行不超过80个字符,用-1作为结束标志),写入`file2.txt`后再读取并显示。文中详细讲解了文件的打开、读取(使用`fgetc()`和`fgets()`)、写入(使用`fputc()`和`fputs()`)及关闭操作,并提供了示例代码和测试说明。
552 5
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
974 3
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
179 2
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
223 2
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
存储 C语言
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
390 3