服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言文件操作之fread函数详解

C语言文件操作之fread函数详解

2022-12-22 15:51韩曙亮 C/C++

fread()函数用来从指定文件中读取块数据,下面这篇文章主要给大家介绍了关于C语言文件操作之fread函数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

前言

二进制文件读写两个重要的函数 , fread 和 fwrite , fread 用于读取文件 , fwrite 用于写出文件 ;

fread / fwrite 函数 既可以操作 二进制文件 , 又可以操作 文本文件 ;

getc / putc 函数 , fscanf / fprintf 函数 , fgets / fgets 函数 , 只能用于操作 文本文件 ;

 

一、fread 函数

fread 函数作用 : 从文件中读取若干字节数据到内存缓冲区中 ;

fread 函数原型 :

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

void *buffer 参数 : 将文件中的二进制数据读取到该缓冲区中 ;

size_t size 参数 : 读取的 基本单元 字节大小 , 单位是字节 , 一般是 buffer 缓冲的单位大小 ;

  • 如果 buffer 缓冲区是 char 数组 , 则该参数的值是 sizeof(char) ;
  • 如果 buffer 缓冲区是 int 数组 , 则该参数的值是 sizeof(int) ;

size_t count 参数 : 读取的 基本单元 个数 ;

FILE *stream 参数 : 文件指针 ;

size_t 返回值 : 实际从文件中读取的 基本单元 个数 ; 读取的字节数是 基本单元数 * 基本单元字节大小 ;

代码示例 : 一次性读满整个缓冲区 ;

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};

  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  fread(buffer, sizeof(char), sizeof(buffer), p);

  // 打印读取的内容
  printf("buffer = %s\n", buffer);

  printf("Main End\n");
  return 0;
}

执行结果 :

C语言文件操作之fread函数详解

 

二、缓冲区受限的情况 ( 循环读取文件 | feof 函数判定文件读取完毕 )

假设缓冲区很小 , 文件很大 , 则需要循环读取文件数据 ;

使用 feof(p) 判定文件是否读取完毕 , 如果返回 true 说明文件没有读取完毕 , 返回 false , 说明文件读取完毕 ;

代码示例 :

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[4] = {0};

  while(!feof(p)){
      memset(buffer, 0, sizeof(buffer));
      // buffer : 将文件读取到内存的位置
      // sizeof(char) : 读取的基本单元字节长度
      // sizeof(buffer) : 读取的基本单元个数,
      //       读取字节个数是 sizeof(buffer) * sizeof(char)
      // p : 文件指针
      fread(buffer, sizeof(char), sizeof(buffer), p);

      // 打印读取的内容
      printf("buffer = %s\n", buffer);
  }

  printf("Main End\n");
  return 0;
}

执行结果 : 读取之后出现乱码 , 这是由于每次读取 10 10 10 字节 , 但是字符串必须要以 ‘\0’ 进行结尾 , 如果没有 ‘\0’ 则会一直读取直到出现 ‘\0’ 字符串结尾位置 ;

C语言文件操作之fread函数详解

 

三、处理乱码问题

为了避免上述打印出现乱码的情况 , char buffer[4] = {0}; 准备了 4 4 4 字节缓冲区 , 每次只使用其中的 3 3 3 个字节 , 这就能保证最后一个字节必定是 ‘\0’ , 打印时就不会出现乱码 ;

代码示例 :

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[4] = {0};

  while(!feof(p)){
      memset(buffer, 0, sizeof(buffer));
      // buffer : 将文件读取到内存的位置
      // sizeof(char) : 读取的基本单元字节长度
      // sizeof(buffer) : 读取的基本单元个数,
      //       读取字节个数是 sizeof(buffer) * sizeof(char)
      // p : 文件指针
      fread(buffer, sizeof(char), sizeof(buffer) - 1, p);

      // 打印读取的内容
      printf("buffer = %s\n", buffer);
  }

  printf("Main End\n");
  return 0;
}

执行结果 : 每次从文件中读取 缓冲区字节数 - 1 个字节 , 则能完整的将文本打印出来 ;

C语言文件操作之fread函数详解

 

四、记录读取的字节个数

fread 函数返回值表示读取到的 基本单元 的个数 , 如果设置了 1KB 的缓冲区 , 但是文件中只有 5 字节 , 则 fread 的返回值就是实际读取到的数据个数 ;

代码示例 :

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};
  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  // 返回值 : fread 函数返回值表示读取到的 基本单元 的个数
  size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p);

  // 打印读取的内容
  printf("buffer = %s , read count = %u\n", buffer, count);

  printf("Main End\n");
  return 0;
}

执行结果 :

C语言文件操作之fread函数详解

 

五、读取到 0 字节的情况

如果 基本单元 大小 4 4 4 字节 , 文件中只有 3 3 3 字节数据 , 则使用 fread 函数读取文件 , 缓冲区设置 1KB , 则实际读取到的基本单元个数是 0 0 0 ;

代码示例 :

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};
  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  // 返回值 : fread 函数返回值表示读取到的 基本单元 的个数
  size_t count = fread(buffer, sizeof(int), sizeof(buffer) - 1, p);

  // 打印读取的内容
  printf("buffer = %s , read count = %u\n", buffer, count);

  printf("Main End\n");
  return 0;
}

执行结果 :

C语言文件操作之fread函数详解

 

六、读取完毕的情况

如果文件已经读取完毕 , 不关闭文件 , 再次调用 fread 函数继续读取 , 则读取到的 基本单元 个数是 0 0 0 ;

使用 feof(p) 判定文件是否读取完毕 , 如果返回 true 说明文件没有读取完毕 , 返回 false , 说明文件读取完毕 ;

代码示例 :

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};
  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  // 返回值 : fread 函数返回值表示读取到的 基本单元 的个数
  size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p);

  // 打印第一次读取的内容
  printf("First fread : buffer = %s , read count = %u\n", buffer, count);

  count = fread(buffer, sizeof(int), sizeof(buffer) - 1, p);

  // 打印第二次读取的内容
  printf("Second fread : buffer = %s , read count = %u\n", buffer, count);

  printf("Main End\n");
  return 0;
}

执行结果 :

C语言文件操作之fread函数详解

 

七、读取文本文件 “\n” 与 读取二进制文件 “\r\n” 区别

以下区别只在 Windows 系统存在 , 在 Linux / Unix 中读取文本数据与二进制数据没有区别 ;

使用 ‘rb’ 方式打开文件 , 读取二进制文件 , 然后调用 fread 函数读取文件 ,

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "rb");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};
  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  // 返回值 : fread 函数返回值表示读取到的 基本单元 的个数
  size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p);

  // 打印第一次读取的内容
  printf("fread : buffer = %s , read count = %u\n", buffer, count);

  // 逐个字节打印读取出数据的 ASCII 码
  int i = 0;
  for(i = 0; i < count; i ++){
      printf("buffer[%d] = %x\n", i, buffer[i]);
  }

  printf("Main End\n");
  return 0;
}

执行结果 : 第 2 2 2 个索引读取出来的值是 0xd 对应 ‘\r’ , 第 3 3 3 个值是 0xa 对应 ‘\n’ ;

注意 : 最后两个字节是空行对应的 “\r\n” ;

fread : buffer = ab
cd
, read count = 8
buffer[0] = 61
buffer[1] = 62
buffer[2] = d
buffer[3] = a
buffer[4] = 63
buffer[5] = 64
buffer[6] = d
buffer[7] = a
Main End

C语言文件操作之fread函数详解

使用 ‘r’ 方式打开文件 , 读取文本文件 , 然后调用 fread 函数读取文件 ,

#include <stdio.h>

int main()
{
  // 使用 "rb" 读取二进制方式打开文件
  FILE *p = fopen("D:\\a.txt", "r");

  // 用于接收读取数据的缓冲区
  char buffer[1024] = {0};
  // buffer : 将文件读取到内存的位置
  // sizeof(char) : 读取的基本单元字节长度
  // sizeof(buffer) : 读取的基本单元个数,
  //       读取字节个数是 sizeof(buffer) * sizeof(char)
  // p : 文件指针
  // 返回值 : fread 函数返回值表示读取到的 基本单元 的个数
  size_t count = fread(buffer, sizeof(char), sizeof(buffer) - 1, p);

  // 打印第一次读取的内容
  printf("fread : buffer = %s , read count = %u\n", buffer, count);

  // 逐个字节打印读取出数据的 ASCII 码
  int i = 0;
  for(i = 0; i < count; i ++){
      printf("buffer[%d] = %x\n", i, buffer[i]);
  }

  printf("Main End\n");
  return 0;
}

执行结果 : 第 2 2 2 个索引读取出来的值是 0xa 对应 ‘\n’ ;

最后的空行只有一个 ‘\n’ ;

fread : buffer = ab
cd
, read count = 6
buffer[0] = 61
buffer[1] = 62
buffer[2] = a
buffer[3] = 63
buffer[4] = 64
buffer[5] = a
Main End

C语言文件操作之fread函数详解

 

总结

到此这篇关于C语言文件操作之fread函数的文章就介绍到这了,更多相关C语言文件操作fread函数内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/shulianghan/article/details/117338844

延伸 · 阅读

精彩推荐
  • C/C++C语言数组实现三子棋应用实例

    C语言数组实现三子棋应用实例

    这篇文章主要为大家详细介绍了C语言数组实现三子棋应用实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Yiiiiiiiiiiiiii3422022-08-16
  • C/C++C语言实现求定积分的方法

    C语言实现求定积分的方法

    这篇文章主要介绍了C语言实现求定积分的方法,涉及C语言操作相关数学函数的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    Chance8802021-02-22
  • C/C++数组中求第K大数的实现方法

    数组中求第K大数的实现方法

    本篇文章是对数组中求第K大数的实现方法进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网3092020-12-07
  • C/C++C语言绘制三角函数曲线

    C语言绘制三角函数曲线

    这篇文章主要为大家详细介绍了C语言绘制三角函数曲线,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Snowalive11122021-07-30
  • C/C++C语言进阶:指针的进阶(1)

    C语言进阶:指针的进阶(1)

    这篇文章主要介绍了C语言指针详解及用法示例,介绍了其相关概念,然后分享了几种用法,具有一定参考价值。需要的朋友可以了解下...

    AKA你的闺蜜7002021-12-28
  • C/C++C语言基于循环链表解决约瑟夫环问题的方法示例

    C语言基于循环链表解决约瑟夫环问题的方法示例

    这篇文章主要介绍了C语言基于循环链表解决约瑟夫环问题的方法,简单描述了约瑟夫环问题并结合实例形式分析了C语言使用循环链表解决约瑟夫环问题的具...

    handsome_ZHANG3722021-06-11
  • C/C++C语言深入细致讲解动态内存管理

    C语言深入细致讲解动态内存管理

    动态内存是相对静态内存而言的。所谓动态和静态就是指内存的分配方式。动态内存是指在堆上分配的内存,而静态内存是指在栈上分配的内存,本文带你...

    菜菜不恰菜8822022-11-24
  • C/C++Visual Studio Code (VSCode) 配置搭建 C/C++ 开发编译环境的流程

    Visual Studio Code (VSCode) 配置搭建 C/C++ 开发编译环境的流程

    记得N年前刚开始接触编程时,使用的是Visual C++6.0,下面这个可爱的图标很多人一定很熟悉。不过今天想尝鲜新的工具 Visual Studio Code 来搭建C/C++开发环境,...

    Hi,出发了4502022-01-17