【C】ASCII 的十六进制字符转文件

news2025/6/9 17:15:46

概述

本项目是我自己使用的

来源于用串口传文件数据到电脑进行分析的时候,需要转换成可以打开的文件

而常用的串口助手大都没有直接保存为二进制文件的功能

也完全可以当作c语言初学者的练习项目(很简单)

需求

用串口传来的文件是如下格式(ASCII字符)

需要将其转化为二进制数据,使其可以打开

如下(上图是记事本打开的文本文件,下图是winhex打开的二进制文件)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GaFPSYFn-1675908462293)(picture/1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2x969fi3-1675908462298)(picture/2.png)]

另外需要运行效率相对较高(有时候会有Gb级文件解码的需要)

附加:便于使用,目前设计的是拖动要转化的文件到程序上,可以自动将其转化并输出文件(带后缀名)到指定目录

方案

核心程序选用C语言设计,本人对C相对熟悉,C语言的执行效率较高,可编译成exe文件

外围输入输出使用bat文件(批处理),获取拖入的文件名,及更改输出的文件名和位置

程序

C

控制台传参

当我们把主函数(main)定义成特殊形式时,我们可以在控制台(cmd)调用exe时向函数传递参数

如下图所示,则可以传入3个参数 第一个参数是1 第二个参数是2 (参数间用空格分开,为char *型)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQ0b8OnZ-1675908462298)(picture/3.png)]

我们把主函数定义为如下形式时即可实现这个功能

int main(int argc, char *argv[])
{

}

argc:是参数数量,上例子中为4(包括一开始的exe文件路径)

argv:是参数的内容

上例中 argv[0]是text.exe的全路径名(一般用不到)

argv[1]是"a1"

argv[2]是"a2"

argv[3]是"a3"

在本项目中,我设计传入的参数有3个,

第一个是被解析文件的全路径(绝对路径)(C:\home\1.txt)

第二个是输出文件名(为了区分,在程序中让这个文件名加上了后缀)(如 outputfile)(支持目录前缀 相对目录)

第三个是文件的后缀名(.jpeg)

输出文件名检测

这个部分是为了应对文件名出现重复的情况

例子:假设要输出的文件名是out ,但是输出目录下有了这个文件,则我需要让他输出out1

如果这个也有了则让他输出out2依次类推

设计是大于某个数(1000000)时则认为出错,也就是out1000000

思路:设计一个缓冲区(char *),将文件名拼接起来(sprintf)输出到缓冲区,之后检测文件是否存在(access)

如果存在则后缀加1,不存在直接创建即可

sprintf是字符串格式化输出的函数,百度连接,和printf用法差不多,只是将输出内容放到了字符串(Add_output)中

access是检测权限的一个函数,百度连接,返回值为0时文件不存在

mallocfree是c的动态分配函数,百度连接

Add_output = (char *)malloc(sizeof(char) *(strlen(Add_output_befor) + strlen(Add_output_after) + 15));

这句的作用是重新分配缓冲区的大小,让其值变成可被sprintf覆写的状态,malloc的用法请自行百度

注意使用后需要free

char *Add_output;
char *Add_output_befor = argv[2];
char *Add_output_after = argv[3];
for (int i = 0;; i++)
{
	Add_output = (char *)malloc(sizeof(char) *(strlen(Add_output_befor) + strlen(Add_output_after) + 15));

	sprintf(Add_output, "%s%d%s", Add_output_befor, i, Add_output_after);
	// puts(Add_output);
	if (access(Add_output, 0) != 0)
		break;
	else
		free(Add_output);
	if (i > 1000000)
	{
		printf("ERROR:output file name error\r\n");
	}
}
//puts(Add_output);

文件的打开与基本读写

使用fopen打开文件,fgetc读取单个字符,feof判断文件末尾,fputc输出内容到文件,fclose关闭文件

这几个函数很常用,不懂的请自行百度

思路:我们到这里已经将输出文件的位置和名字确定好了(上一步),

现在需要判断输入的文件是否可以打开,如果不打开则输出错误信息并退出

之后在打开输出文件,开始为读写做准备

输入文件使用只读模式打开,输出文件使用二进制写模式打开

char *Add_input = argv[1];
FILE *input_fp, *output_fp;
input_fp = fopen(Add_input, "r");
if (input_fp == NULL)
{
	printf("ERROR: failed to open the read file!\r\n");
	fclose(input_fp);
	fclose(output_fp);
	free(Add_output);
	system("pause");
	return 0;
}
output_fp = fopen(Add_output, "wb");
while (!feof(input_fp)) // 读文件
{
	data_zj = fgetc(input_fp);
    /*省略的内容*/
    fputc(data_all, output_fp);
}

格式转化(核心)

这是这个项目的核心,就是将ascii的字符解码成二进制的过程

我们先分析一下字符的样子

如下图,"B5 10 00 "由0-9和A-F来表示16进制的字符,以1Byte为单位,Byte直接用空格隔开

目标则是转化为 0xB5,0x10,0x00

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ZUSOpEu-1675908462299)(picture/1.png)]

思路:

搞一个循环,知道读取到文件尾退出

首先读取一个字符,如果这个字符是空格则跳过这次循环,如果不是空格则再次判断是否到了文件尾(避免出现不合法的字符的情况),文件尾则退出循环

将这个字符转化为数,如Ascii 的’0’到’9’就减去’0’,'A’到’F’就减去’A’加10(0xA代表十进制的10).之后在读取一个字符,并对其转化

将两个字符按顺序拼接起来,输出到文件即可

while (!feof(input_fp)) // 读文件
{
	data_zj = fgetc(input_fp);
	if (data_zj == ' ')
		continue;
	if (feof(input_fp))
		break;
	data_first = Ascll2uchar(data_zj);
	data_last = Ascll2uchar(fgetc(input_fp));
	data_all = (data_first << 4) | data_last;
	// printf("%x ", data_all);
	fputc(data_all, output_fp);
}

时间计算

使用clock函数,在程序开头和结尾分别计算一次时间,相减即可

int begintime, endtime;
begintime = clock();
/*中间程序*/
endtime = clock();
printf("finish\r\nspend %d ms\r\n", endtime - begintime);

完整程序

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

#define uint8_t unsigned char

uint8_t Ascll2uchar(uint8_t input)
{
    if (input >= 'a' && input <= 'z')
        return input - 'a' + 10;
    if (input >= 'A' && input <= 'Z')
        return input - 'A' + 10;
    if (input >= '0' && input <= '9')
        return input - '0';
}
int main(int argc, char *argv[])
{
    int begintime, endtime;
    uint8_t data_all, data_first, data_last;
    uint8_t data_zj;
    FILE *input_fp, *output_fp;

    char *Add_output;
    char *Add_input = argv[1];
    char *Add_output_befor = argv[2];
    char *Add_output_after = argv[3];
    // char *Add_input = "C:\\Users\\HZ12138\\Desktop\\1.txt";
    // char *Add_output_befor = "output";
    // char *Add_output_after = ".jpeg";
    begintime = clock();
    for (int i = 0;; i++)
    {
        Add_output = (char *)malloc(sizeof(char) *
                                    (strlen(Add_output_befor) + strlen(Add_output_after) + 15));

        sprintf(Add_output, "%s%d%s", Add_output_befor, i, Add_output_after);
        // puts(Add_output);
        if (access(Add_output, 0) != 0)
            break;
        else
            free(Add_output);
        if (i > 1000000)
        {
            printf("ERROR:output file name error\r\n");
        }
    }
    puts(Add_output);
    input_fp = fopen(Add_input, "r");
    if (input_fp == NULL)
    {
        printf("ERROR: failed to open the read file!\r\n");
        fclose(input_fp);
        fclose(output_fp);
        free(Add_output);
        system("pause");
        return 0;
    }
    output_fp = fopen(Add_output, "wb");
    while (!feof(input_fp)) // 读文件
    {
        data_zj = fgetc(input_fp);
        if (data_zj == ' ')
            continue;
        if (feof(input_fp))
            break;
        data_first = Ascll2uchar(data_zj);
        data_last = Ascll2uchar(fgetc(input_fp));
        data_all = (data_first << 4) | data_last;
        // printf("%x ", data_all);
        fputc(data_all, output_fp);
    }
    fclose(input_fp);
    fclose(output_fp);
    free(Add_output);
    endtime = clock();
    printf("finish\r\nspend %d ms\r\n", endtime - begintime);
    return 0;
}

批处理文件

使用批处理文件是为了方便的更改输出文件位置和文件名(记事本就能打开更改)

进入当前目录,打开exe文件

其中这个%1指的是获取拖拽到当前批处理上文件的绝对目录

@echo off
path = .\
Ascii2Bin.exe %1 output .jpeg
pause

使用教程

如下图,上面的是可执行文件(c语言编译出来的),中间的是批处理文件,下面的是要转化的文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZLoRF20-1675908462300)(picture/4.png)]

我们将要转化的文件拖入批处理文件中,即可在当前目录生成解码后的文件,并输出信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RUnGOLPZ-1675908462301)(picture/5.png)]在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QvgIlzSW-1675908462303)(picture/6.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ur3T1hGZ-1675908462303)(picture/7.png)]

成品

GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/334242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty相关面试题

文章目录TCP、UDP的区别&#xff1f;同步与异步、阻塞与非阻塞的区别&#xff1f;BIO、NIO、AIO分别是什么&#xff1f;Netty跟Java NIO有什么不同&#xff0c;为什么不直接使用JDK NIO类库&#xff1f;Netty的粘包/拆包是怎么处理的&#xff0c;有哪些实现&#xff1f;说说Net…

网络安全的就业及发展前景如何?

网络空间安全专业简称“网络安全专业”&#xff0c;主要以信息构建的各种空间领域为主要研究对象&#xff0c;包括网络空间的组成、形态、安全、管理等。该专业致力于培养“互联网”时代能够支撑和引领国家网络空间安全领域的具有较强的工程实践能力&#xff0c;系统掌握网络空…

完美!终于有人把《数据结构与算法》讲透彻了(附源码笔记),复杂的问题变简单了

开篇 数据结构是计算机科学与技术专业非常重要的一门核心基础课&#xff0c;计算机科学各个领域以及各种应用软件都要使用相关的数据结构和算法。 本篇的主要目的不是提供关于数据结构和算法的定理及证明。本书采用的模式是利用不同的复杂度改善问题的解决(对于每个问题&…

Spring面试重点(一)——Spring容器

Spring容器 手写Autowired注解 /** 实现spring的Autowired注解 **/ //运行时触发 Retention(RetentionPolicy.RUNTIME) //作用于变量 Target(ElementType.FIELD) public interface Autowired {}public class UserController {Autowiredprivate UserService userService;/*** …

专家说年轻人工资低是能力不行….

我们国家的很多专家总讲究语不惊人死不休&#xff0c;同时他们还很喜欢话风高速原地调头。 最近又有一个碉堡了的专家在大放厥词&#xff0c;就在前几天的首届长白山高峰论坛上中航基金副总经理邓海清发表批评年轻人的言论&#xff0c;邓老板是这么说的&#xff1a;很多年轻人…

数据分析实战项目3:RFM用户分群

目录1、RFM模型介绍2、Excel实际RFM划分案例3、RFM案例3.1 数据加载和基本信息查看3.2 数据预处理和RFM的初始值计算3.3 RFM区间和划分和分值计算3.4 RFM计算结果保存3.4.1 保存到excel3.4.2 保存到数据库3.5 RFM计算结果可视化3.6 结果分析&#xff08;营销建议&#xff09;3.…

[docker]笔记-基础配置

1、docker启动和设置开机启动 [rootlocalhost ~]# systemctl start docker [rootlocalhost ~]# systemctl enable docker 2、更换docker镜像网站&#xff0c;默认docker镜像网站是国外网站&#xff0c;下载镜像非常慢&#xff0c;需要更换为国内网站&#xff0c;以阿里云为例…

android多渠道打包(只编译一次)

众所周知&#xff0c;android 默认工具gradle可以配置多个productFlavors&#xff0c;以此实现配置多个不同版本&#xff0c;渠道的app应用&#xff0c;笔者认为这个编译速度很慢&#xff0c;于是乎有了今天的方案。希望能抛砖引玉为大家带来不一样的思路&#xff0c;废话不多说…

基于蜣螂算法改进的DELM预测-附代码

基于蜣螂算法改进的深度极限学习机DELM的回归预测 文章目录基于蜣螂算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.蜣螂算法4.蜣螂算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1…

QT基础入门【布局篇】消除控件之间的间隔

一、相关参数 layoutLeftMargin: layout内的布局距离边框左端的距离。 layoutTopMargin: layout内的布局距离边框顶端的距离。 layoutRightMargin: layout内的布局距离边框右端的距离。 layoutBottomMargin: layout内的布局距离边框底端的距离。 layoutHorizontalSpacing: layo…

【每日阅读】前端了解的HTTP协议知识(二)

HTTP 简介 HTTP 协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议&#xff1b; HTTP工作原理 HTTP协议工作于客户端-服务端架构上&#xf…

算法导论—近似算法

近似算法基础1. 近似算法的基本概念2. 近似算法的性能分析1. 近似算法的基本概念 很多实际应用问题都是NP-完全问题&#xff0c;这类问题很可能不存在多项式时间算法。一般而言&#xff0c;NP-完全问题可采用以下三种方式处理。 如果问题的输入规模较小&#xff0c;则可以利用…

利用IO工具包拷贝文件夹或者文件

引入依赖 <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version> </dependency> code 拷贝文件夹 PostMapping("/findB00List") CrossOrigin public Result …

(考研湖科大教书匠计算机网络)第三章数据链路层-第十节:以太网交换机的生成树协议STP

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;以太网故障导致的网络问题二&#xff1a;利用冗余链路提高稳定性&#xff08;1&#xff09;概述&#xff08;2&#xff09;冗余链路带来的问题三&a…

Swagger2 3.0的使用

前言 今天使用了以下swagger2 的3.0.0版本&#xff0c;好家伙&#xff0c;好多坑。在这里记录一下&#xff0c;方便查阅。 一、Swagger的简介 官网&#xff1a;https://swagger.io/ Swagger 是一个规范且完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的…

应用监控以及告警实现

前言 一个Java应用 可以不优秀&#xff0c;但是一定不能没有监控方案。否则极大影响排查线上问题的效 以及系统故障的及时告警 。试想 核心应用挂了一个 但是没有配置告警 理想情况几个小时 被自己人发现了 但是万一自己人也没看到或者没关注 那难道让服务一直挂下去么 &#…

Vue框架学习篇(五)

Vue框架学习篇(五) 1 组件 1.1 组件的基本使用 1.1.1 基本流程 a 引入外部vue组件必须要的js文件 <script src"../js/httpVueLoader.js"></script>b 创建.vue文件 <template><!--公共模板内容--></template><script><!…

LaoCat带你认识容器与镜像(实践篇二上)

实践篇主要以各容器的挂载和附加命令为主。 本章内容 本文实操全部基于Ubuntu 20.04 宿主机 > linux服务器本身 Docker > 20.10.22 在开始本章内容之前&#xff0c;我解答一个问题&#xff0c;有小伙伴问我说&#xff0c;有的容器DockerHub官网并没有提供任何可参考的文…

可信AI年度观察 | 智能语音产业需求不断升级,评测重点由技术转向产品

自《新一代人工智能发展规划》发布以来&#xff0c;人工智能发展已上升为国家战略&#xff0c;在“十四五”规划中&#xff0c;更是将人工智能列为科技前沿领域的“最高优先级”&#xff0c;国家政策支持为人工智能产业发展提供良好环境。同时&#xff0c;各行业逐渐重视改善价…

ChatGPT 支持的搜索引擎 Bing 究竟什么样?

微软于2月8日北京时间凌晨在 Redmond 线下举办一场媒体活动&#xff0c;围绕微软的产品以及 AI&#xff0c;公布最新消息。这里我们先回顾一下微软在 AI 上的布局。 2019年&#xff0c;微软向 OpenAI 投资10亿美元&#xff0c;成为了 OpenAI 紧密的合作伙伴&#xff0c;而微软…