首页 > 其他分享 >C语言字符串和十六进制的相互转换方式

C语言字符串和十六进制的相互转换方式

时间:2024-11-10 18:49:52浏览次数:5  
标签:十六进制 16 int 0x00 C语言 char 字符串 out

C语言字符串和十六进制的相互转换方式 - 我就叫宋帅呀 - 博客园

C语言的字符串操作并不像java,Csharp那样提供直接的方法,简单粗暴。所以,在转换的时候往往费力费时,近日做项目正好用到和java程序通讯,java发送过来的数据是十六进制数字组成的字符串,解析的时候颇费心思才算完成,所以,权在此做一笔记,方便以后查看,以及需要帮助的童鞋,当然,有问题欢迎随时交流,一同进步,欧耶!~

一、将数组转换为十六进制同值的字符串

   读取数组中的数字,打印成字符串的时候以2位大写的格式。

完整代码1


#include "stdio.h"
#include "stdlib.h"
#include "string.h"

unsigned char ArrayCom[16] = {
    11, 12, 13, 14, 15, 16, 17, 18,
    19, 20, 21, 22, 23, 24, 25, 26};

unsigned char ArrayHex[16] = {
    0x2c, 0x57, 0x8f, 0x79, 0x27, 0xa9, 0x49, 0xd3,
    0xb5, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

int arrayToStr(unsigned char *buf, unsigned int buflen, char *out)
{
    char strBuf[33] = {0};
    char pbuf[32];
    int i;
    for(i = 0; i < buflen; i++)
    {
        sprintf(pbuf, "%02X", buf[i]);
        strncat(strBuf, pbuf, 2);
    }
    strncpy(out, strBuf, buflen * 2);
    printf("out = %s\n", out);
    return buflen * 2;
}

int main(int argc, const char *argv)
{
    char str[33] = {0};
    char str1[33] = {0};

    printf("将ArrayCom十进制数组转换为十六进制同值的字符串\n");
    arrayToStr(ArrayCom, 16, str);
    printf("ArrayCom: %s\n",str);
    printf("\n");
    printf("将ArrayHex十六进制数组转换为十六进制同值的字符串\n");
    arrayToStr(ArrayHex, 16, str);
    printf("ArrayHex: %s\n",str);


    return 0;
}

输出结果

将ArrayCom十进制数组转换为十六进制同值的字符串
ArrayCom: 0B0C0D0E0F101112131415161718191A

将ArrayHex十六进制数组转换为十六进制同值的字符串
ArrayHex: 2C578F7927A949D3B511000000000000

Process returned 0 (0x0)   execution time : 0.087 s
Press any key to continue.

完整代码2---------------------------


#include <stdio.h> // 包含标准输入输出库,用于打印输出
#include <string.h> // 包含字符串处理库
#include <malloc.h> // 包含动态内存分配库
#include <stdint.h>

unsigned char ArrayCom[16] = {
    11, 12, 13, 14, 15, 16, 17, 18,
    19, 20, 21, 22, 23, 24, 25, 26};

unsigned char ArrayHex[16] = {
    0x2c, 0x57, 0x8f, 0x79, 0x27, 0xa9, 0x49, 0xd3,
    0xb5, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

uint8_t HexToAscii(uint8_t c)
{
	if(c > 9){
		return (c+55);     // 16进制 0A 对应的ascii 'A',两者相差55  -- 可以比照ascii表理解
	}else{
		return (c+48);     // 16进制 01 对应的ascii '1'  两者相差48  -- 可以比照ascii表理解
	}
}

uint8_t*  HexToAsciiStr(uint8_t rcvData[], int len) //方式1
{
	uint8_t temp;
	static uint8_t data[32] = {0}; //可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的
	for(int i = 0; i < len; i++){
		temp = rcvData[i] & 0xf0;   // 取16进制数高位放到 HexToAscii 函数中转成字符
		*(data + i*3) = HexToAscii(temp >> 4);
		temp = rcvData[i] & 0x0f;   // 取16进制数低位放到 HexToAscii 函数中转成字符
		*(data + i*3 + 1) = HexToAscii(temp);
		*(data + i*3 + 2) = ' ';  // 添加空格进行区分
	}
	return data;
}


void  HexToAsciiStr1(uint8_t *inbuf, int len,uint8_t *data) //方式2
{
    #define	IntToASCII(c)	(c)>9?((c)+0x37):((c)+0x30); // 宏定义,将0-15的整数转换为对应的ASCII码
	uint8_t temp;
    int i=0;
	for(i = 0; i < len; i++){
		temp = inbuf[i] & 0xf0;   // 取16进制数高位放到 HexToAscii 函数中转成字符
		*(data + i*3) = IntToASCII(temp >> 4);
		temp = inbuf[i] & 0x0f;   // 取16进制数低位放到 HexToAscii 函数中转成字符
		*(data + i*3 + 1) = IntToASCII(temp);
		*(data + i*3 + 2) = ' ';  // 添加空格进行区分
	}
        *(data + i*3 ) = 0; // 在字符串末尾添加空字符,表示字符串结束
}



int main()
{
	 uint8_t *data = HexToAsciiStr(ArrayCom, sizeof(ArrayCom)); //ret为数组长度
	 printf("string is: %s\n",data);
	 printf("\n");
     uint8_t *data1 = HexToAsciiStr(ArrayHex, sizeof(ArrayHex)); //ret为数组长度
	 printf("string is: %s\n",data1);//

    printf("\n");
   char* out2 = (char *) malloc(sizeof(ArrayCom)*4);	// 动态分配内存,大小为输入数组大小的4倍
     HexToAsciiStr1(ArrayCom, sizeof(ArrayCom),out2); //ret为数组长度
	 printf("out2 string is: %s\n",out2);// 打印 12 34
    free(out2); // 释放之前分配的内存

	 char* out3 = (char *) malloc(sizeof(ArrayHex)*4);	// 动态分配内存,大小为输入数组大小的4倍
     HexToAsciiStr1(ArrayHex, sizeof(ArrayHex),out3); //ret为数组长度
	 printf("out3 string is: %s\n",out3);// 打印 12 34
    free(out3); // 释放之前分配的内存



}

string is: 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A

string is: 2C 57 8F 79 27 A9 49 D3 B5 11 00 00 00 00 00 00

out2 string is: 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A
out3 string is: 2C 57 8F 79 27 A9 49 D3 B5 11 00 00 00 00 00 00

Process returned 0 (0x0)   execution time : 0.079 s
Press any key to continue.

完整代码2---------------------------

二、将十六进制的字符串转换为同值的十六进制数组

下面定义的字符串中的字符只能是0-F的字符,但是不区分大小写的,前面是安装两位为一个数字进行转换,最后一个数字如果还是两位的则正常转换,如果只剩一位的话则在前面补零输出。

完整代码


#include "stdio.h"
#include "stdlib.h"
#include "string.h"


char *strCom = "1D1213AB6FC1718B19202122232425A6";
char *strCom1 = "11121314151617181920212223242526";

int StringToHex(char *str, unsigned char *out, unsigned int *outlen)
{
    char *p = str;
    char high = 0, low = 0;
    int tmplen = strlen(p), cnt = 0;
    tmplen = strlen(p);
    while(cnt < (tmplen / 2))
    {
        high = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;
        low = (*(++ p) > '9' && ((*p <= 'F') || (*p <= 'f'))) ? *(p) - 48 - 7 : *(p) - 48;
        out[cnt] = ((high & 0x0f) << 4 | (low & 0x0f));
        p ++;
        cnt ++;
    }
    if(tmplen % 2 != 0) out[cnt] = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;

    if(outlen != NULL) *outlen = tmplen / 2 + tmplen % 2;
    return tmplen / 2 + tmplen % 2;
}

int main(int argc, const char *argv)
{
    int cnt;
    unsigned char out[33];
    int outlen = 0;

    printf("将十六进制的字符串 strCom 转换为(同值)十六进制数组\n");
    StringToHex(strCom, out, &outlen);
    for(cnt = 0; cnt < outlen; cnt ++)
    {
        printf("%02X ", out[cnt]);
    }

    printf("\n"); //换行
    printf("out[1]:%x\n",out[1]);
    printf("将十进制的字符串 strCom1 转换为(同值)十六进制数组\n");

    StringToHex(strCom1, out1, &outlen);
    for(cnt = 0; cnt < outlen; cnt ++)
    {
        printf("%02X ", out1[cnt]);
    }
    printf("\n");
    printf("out1[1]:%x\n",out1[1]);
    putchar(10);
    return 0;
}

输出结果

将十六进制的字符串 strCom 转换为(同值)十六进制数组
1D 12 13 AB 6F C1 71 8B 19 20 21 22 23 24 25 A6
out[1]:1d
将十进制的字符串 strCom1 转换为(同值)十六进制数组
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
out1[1]:11


Process returned 0 (0x0)   execution time : 0.096 s
Press any key to continue.

三、将十进制字符串转化为十进制数组

完整代码

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char *strCom1 = "11121314151617181920212223242526";

int StringToCom(char *str, unsigned char *out, int *outlen)
{
    char *p = str;
    char high = 0, low = 0;
    int tmplen = strlen(p), cnt = 0;
    tmplen = strlen(p);
    if(tmplen % 2 != 0) return -1;
    while(cnt < tmplen / 2) //1213141516171819
    {
        out[cnt] = (*p - 0x30) * 10 + (*(++p) - 0x30);
        p++;
        cnt ++;
    }
    *outlen = tmplen / 2;
    return tmplen / 2;
}

int main(int argc, const char *argv)
{
    int cnt;
    char str[33] = {0};
    unsigned char out[33];

    printf("将十进制的字符串 strCom1 转换为十六进制数组\n");
    int outlen = 0;
    StringToCom(strCom1, out, &outlen);

    for(cnt = 0; cnt < outlen; cnt ++)
    {
        printf("%02X ", out[cnt]);
    }

    printf("\n");//换行
    printf("out[0]:%d\n",out[0]);
    putchar(10);

    return 0;
}

输出结果

将十进制的字符串 strCom1 转换为十六进制数组
0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A

out[0]:11  //十进制打印


Process returned 0 (0x0)   execution time : 0.091 s
Press any key to continue.

四、简单的使用方法

定义的参数有些为unsigned char,是因为在定义为char的时候,转换为十六进制之后,负数在表示的时候,难看!

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

unsigned char ArrayCom[16] = {
    11, 12, 13, 14, 15, 16, 17, 18,
    19, 20, 21, 22, 23, 24, 25, 26};
unsigned char ArrayHex[16] = {
    0x2c, 0x57, 0x8f, 0x79, 0x27, 0xa9, 0x49, 0xd3,
    0xb5, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

char *strHex = "01aa0304050607083f0add0c0d0e0f00";
char *strCom = "1D1213AB6FC1718B19202122232425A6";

int main(int argc, const char *argv)
{
    int cnt;
    char str[33] = {0};
    unsigned char out[33];
    arrayToStr(ArrayCom, 16, str);

    int outlen = 0;
    StringToHex(strCom, out, &outlen);
    for(cnt = 0; cnt < outlen; cnt ++)
    {
        printf("%02X ", out[cnt]);
    }
    putchar(10);

    return 0;
}

执行结果

标签:十六进制,16,int,0x00,C语言,char,字符串,out
From: https://blog.csdn.net/mailtoxin/article/details/143610771

相关文章

  • (5)---【DDA画线算法】C语言-OpenGL库-计算机图形学
    本次实验项目         DDA画线算法理解与运用。算法介绍        DDA(DigitalDifferentialAnalyzer)画线算法是一种基于数值微分原理的直线生成算法。它主要用于在光栅系统中绘制直线,即在像素点阵中生成直线。DDA算法的核心思想是从一个端点开始,通过增量,逐......
  • 实验4 C语言数组应用编程
    实验任务1:task1.c源代码:1#include<stdio.h>2#defineN43#defineM245voidtest1(){6intx[N]={1,9,8,4};7inti;89printf("sizeof(x)=%d\n",sizeof(x));1011for(i=0;i<N;++i)......
  • 【C语言】解决error C4996: 'fopen': This function or variable may be unsafe. Cons
    几天编译文件的时候报错,编译出错信息:错误1errorC4996:'fopen':Thisfunctionorvariablemaybeunsafe.Considerusingfopen_sinstead.Todisabledeprecation,use_CRT_SECURE_NO_WARNINGS.Seeonlinehelpfordetails.意思就是fopen不安全,推荐你用fopen_s,这个时......
  • 实验4 c语言数组应用编程
    task1:1#include<stdio.h>2#include<stdlib.h>3#defineN44#defineM2567voidtest1(){8intx[N]={1,9,8,4};9inti;1011printf("sizeof(x)=%d\n",sizeof(x));1213for(i=0;i<N;++i)14......
  • TypeScript基础(一)——交替合并字符串
    TypeScript基础(一)——交替合并字符串题设:输入“abc”、“ef”,输出“aebfc”。1、第一次尝试functionmergeAlternately(word1:string,word2:string):string{//采用三元运算符letmax_len=word1.length<word2.length?word2.length:word1.length;/......
  • 字符串和数据输入
     字符串三种定义方法单引号定义法,可以内含双引号双引号定义法,可以内涵单引号可以使用转移字符(\)来将引号解除效用,变成普通字符串。示例如上字符串的拼接通过+号完成(一般用于字面量和变量或变量和变量之间),只能适用于字符串本身。例如:字符串没有办法通过+和(整数、浮点......
  • 洛谷题单入门1顺序结构(C语言版)
    【入门1】顺序结构Hello,World!#include<stdio.h>intmain(){printf("Hello,World!");return0;}输出字符菱形#include<stdio.h>intmain(){printf("*\n");printf("***\n");printf("*****\n&q......
  • Python 深入浅出字符串
    **Python字符串精讲**大家好,我是Giao仔。创作不易请大家多多支持Python的程序中充满了字符串(string),在平常阅读代码时也屡见不鲜。字符串同样是Python中很常见的一种数据类型,比如日志的打印、程序中函数的注释、数据库的访问、变量的基本操作等等,都用到了字符串。......
  • 根据二叉树创建字符串
    题目:606.根据二叉树创建字符串-力扣(LeetCode)给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空......
  • spdlog一个非常好用的C++日志库(十): 十六进制输出spdlog::to_hex
    目录1.引言2.spdlog::to_hex用法3.spdlog::to_hex实现原理4.总结1.引言    在平时调试网络程序时,多数都会用到wireshark抓包工具,在查看某个包的数据都是按照下面这样格式显示的:那么它是怎么做到的呢?其实spdlog的to_hex也能做到这一点,下面就来介绍它的用法和原......