【文件指针+文件顺序读写操作函数】(2)

简介: 1.文件的打开和关闭1.1 什么是文件指针?每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.假如:我们要操作一个文件,名为text.txt ,首先要打开文件,打开文件的同时,操作系统会自动为该文件创建一个文件信息区,专门用来记录该文件的信息。

2.3 fscanf函数和fprintf函数

前面说过,fscanf函数和fprintf函数是格式化输入输出函数。什么是格式化函数呢?

其实格式化函数就是对于不同格式的数据都能够进行输入输出,比如:整型,浮点型,结构体类型等等,这些就是不同格式的数据。


相较于scanf和printf函数,fscanf函数和fprintf只是多了一个参数,即FILE指针所指向的文件。fscanf函数是向FILE的指针指向的文件中读取格式化的数据,fprintf函数是向FILE*的指针指向的文件中写入格式化的数据。


对比如下:

int fscanf ( FILE * stream, const char * format, ... );
int scanf ( const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
int printf ( const char * format, ... );

举一个简单的例子:

向text.txt文件中写入结构体数据

int main()
{
  FILE* pf = fopen("text.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 0;
  }
  struct S
  {
    char name[20];
    int age;
    float score;
  }s = {"zhangsan",20,99.5f};
  fprintf(pf,"%s %d %f", s.name, s.age, s.score);
  fclose(pf);
  pf = NULL;
  return 0;
}


运行成功后,文件中就有了该结构体的数据。


274cf04d64494ee0ac6868db619aebb6.png

对于fscanf来说亦是如此:


b03697d4f4c647c0956fe6f8b3fa91f9.png

以读的方式打开该文件,对其中的数据进行读取。读取后,打印出来看即可。


s.name不用&的原因是,s.name是一个数组名,表示首元素地址,不需要&,而其他的age和score则需要&。


前面说过,这几个函数都是适用于所有输入流输出流,那么就包括了键盘(标准输入流),屏幕(标准输出流)。

int main()
{
  int ch = fgetc(stdin);
  fputc(ch, stdout);
}

此时,我们会从键盘中读取一个字符,写入到屏幕中。


1e92a0c025f6499eb4989b309f1ae896.gif

对于其他函数也是如此。仍可以从键盘中读取数据,写入到屏幕上。

2.4 fwrite函数和fread函数

上面提到,fwrite函数和fread函数是以二进制的形式进行写入和读取的。

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

先来看看fwrite在库中的声明。

fwrite函数是向stream这个流中一次写count个大小为size的ptr指向的内容。

看不懂没关系,举个例子:

typedef struct S
{
  char name[20];
  int age;
  float score;
}S;
int main()
{
  S s = { "zhangsan",20,95.5f };
  FILE* pf = fopen("text.txt", "wb");
  if (pf == NULL)
  {
    perror("fopen");
    return 0;
  }
  fwrite(&s, sizeof(S), 1, pf);
  fclose(pf);
  pf = NULL;
  return 0;
}

此时我们创建了一个结构体,该结构体有三个成员,我们以二进制写入的形式打开文件进行写入,此时向pf指向的文件中写入s这块空间,一次写入1个sizeof(S)大小的内容。

运行成功后,打开text.txt文件:

3bfba0b2470c4d199cb243f648c12f87.png

你会发现出了拼音zhangsan,其他的都看不懂,没关系,因为这是二进制形式。

看不懂并不代表代码是错误的。


既然我们看不懂,我们就让编译器来看,下面我们以二进制读取的方式,向文件中读取数据出来。

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

既然是读取,那么就是跟写入相反而已。

从stream流指向的文件中读取ptr这块空间的内容,一次读取count个大小为size个字节的内容。

typedef struct S
{
  char name[20];
  int age;
  float score;
}S;
int main()
{
  S s = { 0 };
  FILE* pf = fopen("text.txt", "rb");
  if (pf == NULL)
  {
    perror("fopen");
    return 0;
  }
  fread(&s, sizeof(S), 1, pf);
  printf("%s %d %f", s.name, s.age, s.score);
  fclose(pf);
  pf = NULL;
  return 0;
}

此时我们向pf流指向的文件中读取s这块空间的内容,一次读取1个大小为sizeof(S)个字节的内容。读取成功后,我们就打印出来看看。

ffb248a291e7489b8f4b2ffc05a08e77.png

打印结果确实符合预期。

总结:fwrite 和fread函数是向文件中以二进制的形式写入和读取文件的。

相关文章
|
22天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
67 3
|
29天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
51 4
|
2月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
2月前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
2月前
利用指针函数
【10月更文挑战第2天】利用指针函数。
20 1
|
2月前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
26 2
|
3月前
|
Linux
在Linux内核中根据函数指针输出函数名称
在Linux内核中根据函数指针输出函数名称
|
4月前
|
程序员 C语言
指针在函数参数和返回值中的使用
指针在函数参数和返回值中的使用
69 9
|
4月前
|
存储 搜索推荐 C语言
C语言中的指针函数:深入探索与应用
C语言中的指针函数:深入探索与应用
|
4月前
|
C++
C++通过文件指针获取文件大小
C++通过文件指针获取文件大小
33 0