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

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

1.文件操作

1.1 概述:

我们进行的所有操作都是在计算机内存中进行的,并且我们所操作的数据也是存放在计算机内存中的,一旦我们退出了程序,内存空间就会被释放并回收,而这个过程中我们所操作的所有的数据也将不复存在。如此,我们无法将数据真正保留下来,只能在每次运行程序时重新进行输入,重新录入信息,使用起来极为不便。

1.1.1 为什么使用文件:

我们希望将数据保留在本地,只有当我们进行删除操作时,才将对应的数据删除掉,即尝试实现数据的持久化。而我们实现数据持久化的方式一般有两种:使用数据库或将数据存放至本地磁盘中。

目前还没有接触到数据库的知识,于是我们便通过学习文件操作,来将我们的数据存放至我们计算机的本地硬盘中,从而实现数据的持久化。

1.1.2 什么是文件:

我们通常所说的文件,一般是指存放在我们计算机本地硬盘上的文件。但是在我们的程序设计中(根据文件功能分类),指的是程序文件与数据文件两种文件。

①.程序文件:

程序文件主要包括源程序文件、目标文件和可执行程序文件。

源程序文件(后缀为 .c)

目标文件( Windows 环境下后缀为 .obj)

可执行程序文件( Windows 环境下后缀为 .exe)

②.数据文件:

数据文件的内容不一定是程序,而是程序运行过程中所进行读写的数据,比如程序运行中需要从中读取的数据,或者程序运行完毕所输出的文件。

今天所讨论的,正是数据文件的相关操作

在前面所有内容的学习中,我们所有的输入输出,其操作对象都是终端,均为从键盘读取输入内容,并将处理结果输出致我们的计算据显示器上进行反馈。而今天我们的目的则是将数据信息输入至我们的本地磁盘上,当我们想要对数据进行操作时,便从本地硬盘进行读取。


③.文件名:

文件和我们人类有自己的名字一样,也需要有一个文件标识符,文件名的存在就是为了便于我们进行识别和引用。

而一个文件的文件名由三部分组成:文件路径 + 文件名主干 + 文件后

以文件名“ c:\code\test.txt ”为例:

文件路径为“ c:\code\ ”,表示文件存放在硬盘 C 盘下的 code 文件夹内。

文件名主干为“ test ”,表示该文件的文件名为 test。

文件后缀为“ .txt ”,表示该文件的文件类型为文本文件。

2. 文件顺序读写:

2.1 文件的打开和关闭:

我们在使用或操作我们的文件之前,首先需要在我们的程序中及将其打开

①.文件指针:

首先需要了解一下文件指针这个概念,这是因为不光是文件的打开与关闭,包括后面我们在对我们的文件进行操作时,也都是通过文件指针实现的。

在缓冲文件系统中,最关键的一个概念就是“ 文件类型指针 ”,即我们通常所说的“ 文件指针 ”。并且我们要知道,我们使用的每一个文件都在内存中开辟了相应的文件信息区,用于存放该文件的相关信息,并且这些信息都保存在一个结构体变量中。

并且这样的结构体类型是有系统声明的,取名为 FILE。

例如在 Visual Studio 的头文件stdio.h中(非自定义结构体类型)就有该类型的声明:

struct _iobuf 
{
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
};
typedef struct _iobuf FILE;

使用不同的 C 语言编译器,FILE 类型中所包含的信息可能不完全相同,但是都大同小异。每当我们打开一个本地文件时,系统就会依据我们打开的文件的情况自动创建出一个 FILE 结构的变量,并填充该结构内的信息。而这个由系统创建出来并填充的 FILE 结构变量,就是通过一个 FILE 类型文件指针类进行调用和维护的。

FILE* p;
//定义一个文件指针p

像这样,我们就能创建出一个文件指针,而接下来就可以使这个文件指针 p 指向某个文件信息区(FILE 类型的结构体变量),并通过该文件信息区中所保存的信息来访问本地硬盘内的文件了。通过使用文件指针就可以找到与其相关联的文件了。


②.文件的打开与关闭:

应在读写文件之前打开文件,并在文件读写结束后关闭文件。同时ANSI C规定,使用 fopen 函数(file open)来打开文件,用 fclose 函数(file open)来关闭文件。

什么是ANSI C、ISO C、C89、C90标准?

随着C语言使用得越来越广泛,出现了许多新问题,人们日益强烈地要求对C语言进行标准化。1983年,美国国家标准协会(ANSI)组成了一个委员会,X3J11,为了创立C的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,这个版本的语言经常被称作ANSI C,或有时称为C89(为了区别C99)在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会(ANSI)采纳为ISO/IEC 9899:1990。这个版本有时候称为C90或者ISO C。综上,ANSI C、ISO C、C89、C90其实是同一种标准。


open 函数的使用方式为:

FILE* p = fopen(const char* filename, const char* mod);

1.其中“ const char* filename ”指文件名(是字符串,文件名即文件标识符)。

2.其中“ const char* mod ”指文件打开模式(也是字符串,后面会列出)

int main()
{
  //打开文件:
  FILE* p = fopen("test.txt", "r");
  //以"r",即只读模式打开文件c:\code\test.txt
    //默认路径为.c文件同目录下
  if (p == NULL)
  //判断文件打开是否成功
  {
    perror("FILEOPEN");
    //打开失败打印错误原因并退出
    return 1;
  }
    printf("success\n");
  return 0;
}

fclose 函数的使用方式为:

fopen(FILE* strname);
• 1

“ FILE* strname ”指的是指向期望关闭文件的文件指针。

因为我们在打开文件时没有特意注明路径,则默认路径为 .c 文件的同目录下。为了验证我们代码的正确性,我们在该目录下创建“ test.c ”文件用于代码测试:

458afd401c4340538096a933e1b32059.png

int main()
{
  //打开文件:
  FILE* p = fopen("test.txt", "r");
  //以"r",即只读模式打开文件c:\code\test.txt
  if (p == NULL)
  //判断文件打开是否成功
  {
    perror("FILEOPEN");
    //打开失败打印错误原因并退出
    return 1;
  }
  printf("open success\n");
  //验证文件是否成功打开
  fclose(p);
  p = NULL;
  if (p == NULL)
  {
    printf("close success\n");
    //验证文件是否成功关闭
  }
  return 0;
}

3cbee6e5bb35426a850b8cda8e8becdf.png

③.文件打开模式:

c8905e1c225a42f897ac086a0431017a.jpg

2.2.文件的顺序读写:

2e1bdbc1c45e4dc9a9b38c43b7983a40.jpg这其中较为常用的就是 fputc 函数与 fgetc 函数,我们一般就通过这两个函数来实现对文件内容的顺序读写。

这两个函数的使用方式为:

fputc(const char charname, FILE* strname);
fget(FILE* strname);

首先文本文件 test.txt 中的内容为空,没有内容

接下来我们使用“ 写 ”模式打开该文件,并在判断非空后使用 fputc 函数来进行顺序写入:

int main()
{
    FILE* p = fopen("test.txt", "w");
    //文件打开模式为“写”
    if (p == NULL)
    {
      perror("FILEOPEN");
      return 1;
    }
    char ch = 'a';
    for (ch = 'a'; ch <= 'z'; ch++)
    {
      fputc(ch, p);
        //使用 fputc 函数顺序写入小写字符a~z
    }
    fclose(p);
    p = NULL;
    return 0;
}

我们等待程序编译运行并完成数据写入后关闭程序,这时我们来到本地文件中查看硬盘中本地文件的数据写入情况:

1baf81ce1c8c4218b0da1887fd0efd2d.png

我们看到本地文件中的内容已经实现了数据的顺序写入。

相关文章
|
25天前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
25天前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
1月前
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
|
1月前
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
|
5月前
|
C语言
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
C语言进阶——sprintf与sscanf、文件的随机读写(fseek、ftell、rewind)
43 0
|
存储 缓存 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(下)
|
存储 C语言
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)
【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识(中)
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
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)
1073 0
|
6天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
21 6