【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

相关文章
|
23天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
73 3
|
2月前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
2月前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
2月前
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
|
6月前
|
C语言
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
48 0
|
存储 缓存 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
|
编译器 数据库 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(上)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(上)
|
C语言 BI 人工智能
C语言及程序设计进阶例程-36 文件的随机读写
贺老师教学链接 C语言及程序设计进阶 本课讲解 示例:写到尾再从头读 #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; int main() { int a[10], b[10], i; FILE *iofile; if((iofile=fopen("f1.dat","w+"))==NULL)
1077 0
|
19天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
39 10
|
19天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
42 9