IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【Linux编程】4种方法将bin文件生成C语言格式的头文件数组 -> 正文阅读

[C++知识库]【Linux编程】4种方法将bin文件生成C语言格式的头文件数组

最近博主遇到一个小需求,需要将一个bin文件转换成C语言的数组,然后在代码里面操作这个数组,进行读写操作,最后生成另一个文件。

这个需求的核心是如何将bin转换成C语言的数组形式,本文将介绍以下4种方法:

方法一、使用C语言编写一个小的工具,利用fopen/fread/fwrite等函数来完成;

方法二、利用python脚本来完成;

方法三、利用shell命令hexdump来完成;

方法四、利用shell命令xxd来完成。


一、使用C语言编写小工具

这个比较简单,我们直接看源码:


#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

typedef unsigned char u8;
typedef unsigned int  u32;

static int file_read_bin_data(char *file, u8 *buf, int size)  
{  
    FILE *fp;  
      
    if((fp=fopen(file, "rb")) == NULL) {  
        printf("Can not open the file: %s \n", file);  
        return -1;  
    }  
	
    fread(buf, sizeof(u8), size, fp);
	
    fclose(fp); 

	return 0;	
} 

static u32 file_get_bin_size(char *file)  
{     
    u32  size = 0;     
    FILE  *fp = fopen(file, "rb");     
    if (fp) {        
        fseek(fp, 0, SEEK_END);        
        size = ftell(fp);        
        fclose(fp);     
    }     
    return size;  
} 

int file_out_handle(char *out_file, u8 *buf, u32 size)  
{  
    FILE *fp; 
    int i,j,k,n;  
    int fd ;
    char pbuf[10]={0};  
    char mfgimage[4096*2];
 
    if((fp=fopen(out_file, "wa+"))==NULL) {  
        printf( "\nCan not open the path: %s \n", out_file);  
        return -1;  
    }  
    k=0; 
    for(i = 0; i < size; i++) {  
		k++;  
		sprintf(pbuf,"0x%02x", buf[i]);  
		fwrite(pbuf,strlen(pbuf),1,fp); 
		
		if(k != 16)  
			fwrite(", ", strlen(", "),1,fp);  
		else  
			fwrite(",", strlen(","),1,fp);
		
		if(k == 16) {  
			k=0;  
			fwrite("\n", strlen("\n"),1,fp);  
		}  
    }  
	
	fwrite("\n", strlen("\n"),1,fp);
    
    fclose(fp); 
	
	return 0;
}   
 
int main(int argc, const char *argv[])  
{ 
	u8 *buf = NULL;  
	u32 size;  
	char *src_bin = NULL;  
	char *dst_file= NULL; 

	if (argc != 3) {
		printf("Error param input !\r\n");
		printf("Usage: %s src_bin out_file\e\n", argv[0]);
		exit(1);
	}
	
	src_bin = (char *)argv[1];
	dst_file = (char *)argv[2];
	size = file_get_bin_size(src_bin);
	
	buf = (u8 *)malloc(sizeof(u8) * size); 
	if (buf) {	
		file_read_bin_data(src_bin, buf, size);		
		file_out_handle(dst_file, buf, size);		
		free(buf);
	}
	
    return 0;  
}  
 

我们来测试下:

#编译生成小工具
gcc -o bin2array.exe bin2array.c

#执行转换
./bin2array test.bin test.exe

#查看原来的bin文件的内容
cat test.bin

#查看转换后的内容
cat test.exe

效果如下:

?二、使用python脚本实现

见源码:

### bin file change to C array ###

import os
import sys
import struct

def read_data_from_binary_file(filename, list_data):
    f = open(filename, 'rb')
    f.seek(0, 0)
    while True:
        t_byte = f.read(1)
        if len(t_byte) == 0:
            break
        else:
            list_data.append("0x%.2x" % ord(t_byte))
    f.close()

def write_data_to_text_file(filename, list_data, data_num_per_line):
    f_output = open(filename, 'w+')
    if ((data_num_per_line <= 0) or data_num_per_line > len(list_data)):
        data_num_per_line = 16
        print('data_num_per_line out of range,use default value\n')
    f_output.write('    ')
    for i in range(0,len(list_data)):
        if ( (i != 0) and (i % data_num_per_line == 0)):
            f_output.write('\n    ')
            f_output.write(list_data[i]+', ')
        elif (i + 1)== len(list_data):
            f_output.write(list_data[i])
        else:
            f_output.write(list_data[i]+', ')
    f_output.write('\n')
    f_output.close()

def bin_2_c_array(src,dest):
    input_f = src
    output_f = dest
    data_num_per_line = 16
    list_data = []
    read_data_from_binary_file(input_f, list_data)
    write_data_to_text_file(output_f, list_data, data_num_per_line)

if __name__ == '__main__':
        bin_2_c_array(sys.argv[1], sys.argv[2])

我们测试下:

三、使用shell脚本hexdump实现

见源码:

#!/bin/bash -e 

in_file=$1
out_file=$2

### below is using linux shell cmd: hexdump

out_data0=`hexdump -C $in_file | awk '{ print "0x"$2", 0x"$3", 0x"$4", 0x"$5", 0x"$6", 0x"0x$7", 0x"$8", 0x"$9", 0x"$10", 0x"$11", 0x"$12", 0x"$13", 0x"$14", 0x"$15", 0x"$16", 0x"$17","}'`
#echo "$out_data0"

# delete all strings after "0x,"
out_data1=${out_data0%%0x,*}
#echo "$out_data1"

# delete all strings after ", 0x|"
out_data2=${out_data1%%, 0x|*}
#echo "$out_data2"

echo "$out_data2" > $out_file

其核心语句就是hexdump那一行,巧妙利用hexdump的输出然后做转换,我们来看下效果:

?

四、使用shell脚本xxd实现

?见源码:

#!/bin/bash -e 

in_file=$1
out_file=$2

out_data0=`xxd -i -c 16 $in_file`
#echo "$out_data0"

# delete all strings before '{'
out_data1=${out_data0##*\{}
#echo "$out_data1"

# delete all strings after '}'
out_data2=${out_data1%%\}*}
#echo "$out_data2"

echo "$out_data2" > $out_file

其核心就是xxd命令的调用,我们来看下效果:


下面来一张4种方法生成的对比图:


好了,本次的分享就到这,有兴趣或者有疑问的,欢迎在评论席提出来,希望能够帮助到你。?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-25 12:01:58  更:2021-08-25 12:03:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 6:24:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计