简体   繁体   English

将字节数组/字符数组转换为C中的十六进制字符串

[英]Convert byte array / char array to hexidecimal string in C

I think my understanding of bytes arrays and char arrays is causing me some issues, here is my problem: 我认为我对字节数组和字符数组的理解导致了一些问题,这是我的问题:

I have an application that pulls messages from Websphere MQ and sends them onto a target system. 我有一个应用程序从Websphere MQ中提取消息并将它们发送到目标系统。

A MQ message has a MQBYTE24 (byte array 24 essentially) that represents the MSGID of the message. MQ消息具有MQBYTE24(本质上是字节数组24),表示消息的MSGID。 My goal is to convert this to a hexidecimal string. 我的目标是将其转换为十六进制字符串。

On the WMQ explorer on my Linux box message 1 in the queue has a message identifier of "AMQ QM01" (at least that it what it looks like), and the bytes are below as displayed in the explorer: 在我的Linux机器上的WMQ资源管理器中,队列中的消息1具有消息标识符“AMQ QM01”(至少它看起来像它),并且资源管理器中显示的字节如下:

00000   41 4D 51 20 51 4D 30 31--20 20 20 20 20 20 20 20  |AMQ QM01        |
00010   BD F4 A8 4E A2 A3 06 20--                         |...N...         |

Now when my code runs I pick up that same message id and try convert it to a hex string. 现在,当我的代码运行时,我会获取相同的消息ID并尝试将其转换为十六进制字符串。

The exact message id while debugging is: 调试时确切的消息ID是:

AMQ QM01 \\275\\364\\250N\\242\\243\\006 AMQ QM01 \\ 275 \\ 364 \\ 250N \\ 242 \\ 243 \\ 006

And after running through my conversion (code below) i get: 在完成我的转换(下面的代码)后,我得到:

414D5120514D30312020202020202020FFFFFF4EFFFF6 414D5120514D30312020202020202020FFFFFF4EFFFF6

As you can see it is slightly different to the one that the WMQ Explorer shows, any idea what i am doing wrong here? 正如您所看到的,它与WMQ Explorer显示的略有不同,任何想法我在这里做错了什么?

I assume it is me converting from the MQBYTE24 to char....something is going wrong there... 我假设是我从MQBYTE24转换为char ......那里出了点问题......

Below is a small sample program that produces the "wrong result".....i assune i must use a byte array instead of char? 下面是一个小样本程序,产生“错误的结果”.....我支持我必须使用字节数组而不是char?

The output for the following is: 以下输出为:

Result: 414D5120514D30312020202020202020FFFFFF4EFFFF6 结果:414D5120514D30312020202020202020FFFFFF4EFFFF6

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

int main(){   
    char name[41]="AMQ QM01        \275\364\250N\242\243\006";
    char buffer[82]="";
    char *pbuffer = buffer;
    FILE *fp_1;
    FILE *fp_2;
    int size;
    char *buffer_1 = NULL;
    char *buffer_2 = NULL;

    int rc = convertStrToHex(buffer, name);
    printf( "Result: %s\n", pbuffer ); 
    }
    return 0;
}

int convertStrToHex(char *buffer, char str[10]){
    int len = strlen(str);
    int i;

    for( i = 0; i < len ;i++ ){
        sprintf(buffer, "%X", str[i]);
        buffer +=2;
    };
}

Thanks for the help :-) 谢谢您的帮助 :-)

Lynton 林顿

Depending on the compiler and platform char is signed or not and printf's behaviour is different. 根据编译器和平台,char是否已签名,printf的行为是不同的。

Just cast str[i] to unsigned char (or change the type of str in the function's prototype) and it will work. 只需将str [i]强制转换为unsigned char(或更改函数原型中str的类型),它就可以工作了。 For example (prototype changed): 例如(原型改变):

int convertStrToHex(char *buffer, unsigned char str[10]){
    int len = strlen(str);
    int i;

    for( i = 0; i < len ;i++ ){
        sprintf(buffer, "%X", str[i]);
        buffer +=2;
    };
}

BTW: it considered as unsafe to pass a string without it's allocated length and to use sprintf. BTW:在没有分配长度的情况下传递字符串并使用sprintf被认为是不安全的。 You should use snprintf with the real length of buffer or at least handle the size limit yourself inside the loop. 您应该使用具有实际缓冲区长度的snprintf,或者至少在循环内处理大小限制。 In case strlen(str) is larger than buffer's size * 2. 如果strlen(str)大于缓冲区的大小* 2。

尝试

sprintf(buffer, "%X", (unsigned char)str[i]);

As several other answers already point out, you need to cast the characters to unsigned char to avoid their being padded with FF to fill a 32-bit int's worth of bytes. 正如其他几个答案已经指出的那样,你需要将字符转换为unsigned char以避免用FF填充以填充32位int的字节值。 But there's actually another issue: that lone number 6 at the end will only print as one character in the output. 但实际上还有另一个问题:最后单独的数字6只会在输出中打印为一个字符。 You want each character to take up exactly two positions, so you need a zero-padded field specifier. 您希望每个角色恰好占据两个位置,因此您需要一个零填充字段说明符。 Putting it all together, you get 总而言之,你得到了

sprintf(buffer, "%02X", (unsigned char)str[i]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM