C\C++实现读写二进制文件的方法详解

 更新时间:2023年03月30日 11:25:43   作者:iBlackAngel  
这篇文章主要为大家详细介绍了C\C++实现读写二进制文件的方法,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下

读写二进制文件

打开文件

fopen() 函数用来创建一个新文件或者打开一个已有的文件,该函数返回一个 FILE 对象的指针,函数原型:

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

pathname 是指向文件路径的字符串指针,mode 访问模式包括以下几种:

ModeDescription
r以读方式打开文件
w以写方式打开文件,如果文件不存在将创建一个新文件,如果文件已经存在则截断为零长度,重新写入
a以追加方式打开文件(在文件尾部写入),如果文件不存在将创建一个新文件
r+以读写方式打开文件
w+以读写方式打开文件,如果文件不存在将创建一个新文件,否则截断为零长度
a+以读与追加方式打开文件,如果文件不存在将创建一个新文件,输出总是添加到文件尾部

访问模式字符串还可以包含字母 “b” 作为最后一个字符或上述两个字符字符串中任何一个字符之间的字符。这完全是为了兼容 C89;在所有符合 POSIX 的系统上忽略 “b” 字符,包括 Linux。(其他系统可能会以不同的方式处理文本文件和二进制文件,如果您对二进制文件进行 I/O 操作,并且希望您的程序可以移植到非UNIX环境,则添加“b”可能是一个好主意。)

二进制 I/O 函数

读取函数

#include <stdio.h>

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

从给定流 stream 读取数据到 ptr 所指向的数组中。

  • ptr – 指向带有最小尺寸 size*nmemb 字节的内存块的指针。
  • size – 读取的每个元素的大小,以字节为单位。
  • nmemb – 元素的个数,每个元素的大小为 size 字节。
  • stream – 指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。

当执行成功时,fread() 返回读取到的数据大小,该大小仅当 size 为 1 时等于传输的字节数。如果发生错误,或到达文件结尾时,返回值为短计数(或零)。

fread() 不区分文件结尾和错误,调用者必须使用 feof() 和 ferror() 来确定发生了什么。

示例代码:

#include <stdio.h>
#include <stdint.h>     // included for uint8_t

int main(int argc, char const *argv[]) {
    uint8_t buf[4096] = {0x00};
    FILE *fp = fopen("/usr/bin/prince", "r");
    size_t size = fread(buf, sizeof(uint8_t), sizeof(buf), fp);
    fclose(fp);
    return 0;
}

检查文件结尾 (end-of-file)

#include <stdio.h>

int feof(FILE *stream);

函数 feof() 测试指向流的文件结束指示符(end-of-file indicator),如果设置了,则返回非零值。文件指示符只能通过函数 clearerr() 清除。

通俗地理解,就是在二进制文件读取过程中,通过 feof() 判断是否已经到达文件结尾。所以上面示例的完整版将类似这样:

#include <stdio.h>
#include <stdint.h>     // included for uint8_t

static void print_data(const uint8_t *data, size_t len) {
    for (size_t i = 0; i < len; ++i) {
        if (i != 0 && i % 16 == 0) printf("\n");
        printf("%02x ", data[i]);
    }
    printf("\n");
}

int main(int argc, char const *argv[])
{
    uint8_t buf[4096] = {0x00};
    size_t size = 0;
    FILE *fp = fopen("/usr/bin/xxd", "r");
    if (fp == NULL) return 1;
    while (!feof(fp)) {
        size = fread(buf, sizeof(uint8_t), sizeof(buf), fp);
        print_data(buf, size);
        // do something...
    }
    fclose(fp);
    return 0;
}

写入函数

#include <stdio.h>

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

把 ptr 所指向的数组中的数据写入给定的 stream 流中。

  • ptr – 指向需要写入到文件中的数组的指针
  • size – 写入的每个元素的大小,以字节为单位
  • nmemb – 元素的个数,每个元素的大小为 size 字节
  • stream – 指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。

当执行成功时,fwrite() 返回写入到文件的数据大小,该大小仅当 size 为 1 时等于传输的字节数。如果发生错误,返回值与 size*nmemb 不相等。

示例代码:

#include <stdio.h>
#include <stdint.h>     // included for uint8_t

int main(int argc, char const *argv[]) {
    uint8_t buf[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    FILE *fp = fopen("/tmp/hello.bin", "w");
    size_t size = fwrite(buf, sizeof(uint8_t), sizeof(buf), fp);
    fclose(fp);
    return 0;
}

到此这篇关于C\C++实现读写二进制文件的方法详解的文章就介绍到这了,更多相关C++读写二进制文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 最新C语言中getchar的使用

    最新C语言中getchar的使用

    getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和Tab) ,getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,本文给大家介绍getchar的使用,感兴趣的朋友跟随小编一起看看吧
    2022-12-12
  • C++中传值、传地址和传引用究竟有哪些区别

    C++中传值、传地址和传引用究竟有哪些区别

    指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元,而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已,这篇文章主要给大家介绍了关于C++中传值、传地址和传引用究竟有哪些区别的相关资料,需要的朋友可以参考下
    2021-07-07
  • C++ std::function的用法详解

    C++ std::function的用法详解

    这篇文章主要介绍了C++ std::function使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • Qt入门学习之数据库操作指南

    Qt入门学习之数据库操作指南

    Qt SQL模块为数据库提供了编程支持,Qt支持很多种常见的数据库,如 MySQL Oracle、MS SQL Server、SQLite等,下面这篇文章主要介绍了这篇文章主要给大家介绍了关于Qt入门学习之数据库操作指南的相关资料,需要的朋友可以参考下
    2022-08-08
  • C++ OpenCV中几种基本的图像处理方式

    C++ OpenCV中几种基本的图像处理方式

    大家好,本篇文章主要讲的是C++ OpenCV中几种基本的图像处理方式,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C语言删除输入字符串中的空格示例代码

    C语言删除输入字符串中的空格示例代码

    最近工作中遇到了需求,要删除字符串中的所有空格,就要筛选出空格字符,这篇文章主要给大家介绍了关于利用C语言删除输入字符串中的空格的相关资料,需要的朋友可以参考下
    2022-12-12
  • opencv提取轮廓大于某个阈值的图像

    opencv提取轮廓大于某个阈值的图像

    这篇文章主要为大家详细介绍了opencv提取轮廓大于某个阈值的图像,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 区分c++中的声明与定义

    区分c++中的声明与定义

    这篇文章主要介绍了如何区分c++中的声明与定义,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08
  • C++ 排序插入排序实例详解

    C++ 排序插入排序实例详解

    这篇文章主要介绍了C++ 排序插入排序实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • 利用Matlab绘制有趣图像的示例代码

    利用Matlab绘制有趣图像的示例代码

    这篇文章主要为大家总结了一些利用Matlab绘制的有趣好看的图像的示例代码。文中的示例代码简洁易懂,感兴趣的小伙伴可以动手试一试
    2022-03-03

最新评论