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

4
我认为我对字节数组和字符数组的理解存在一些问题,以下是我的问题:
我有一个应用程序,从Websphere MQ中提取消息并将其发送到目标系统。
MQ消息具有代表消息的MSGID的MQBYTE24(基本上是字节数组24)。我的目标是将其转换为十六进制字符串。
在我的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...         |

现在当我的代码运行时,我选择相同的消息ID并尝试将其转换为十六进制字符串。
在调试时,确切的消息ID是:
AMQ QM01 \275\364\250N\242\243\006
通过运行以下代码进行转换后,我得到的结果如下所示:
414D5120514D30312020202020202020FFFFFF4EFFFF6
你可以看到它与WMQ Explorer显示的略有不同,请问我在这里做错了什么?
我认为这是我从MQBYTE24转换为char时出了问题…...
以下是一个产生“错误结果”的小样本程序.....我想我必须使用字节数组而不是char?
以下是以下代码的输出结果:
结果: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;
    };
}

谢谢您的帮助 :-)
Lynton

那些是转义序列吗?C sprintf 如何处理它们?另外,为什么要使用 char *pbuffer = buffer?在 printf 中直接使用 'buffer' 不就可以了吗? - Aaron Gage
@AaronGage:它们是八进制字符转义。 - Ernest Friedman-Hill
在调用convertStrToHex之前,您真的,真的应该为其指定原型。要么将定义(它本身就是原型)移动到main之前,要么在包含文件后添加普通原型:int convertStrToHex(char*,char*); - pmg
这只是一个测试程序……我通常都有原型的;-) - Lynton Grice
3个回答

2

根据编译器和平台的不同,char类型可能是有符号的或无符号的,printf函数的行为也会有所不同。

只需将str[i]强制转换为unsigned char(或更改函数原型中的str类型),即可解决问题。例如(原型已更改):

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;
    };
}

顺便说一下:传递一个字符串时,不带其分配的长度并使用sprintf被认为是不安全的。您应该使用实际缓冲区长度的snprintf,或者至少在循环内部处理大小限制。如果strlen(str)大于缓冲区大小的两倍。


1

尝试

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

1

正如其他答案已经指出的那样,您需要将字符转换为unsigned char,以避免它们被填充为FF以填充32位int的字节数。但实际上还有另一个问题:结尾处的单个数字6只会在输出中打印一个字符。您希望每个字符占据确切的两个位置,因此需要使用零填充字段说明符。将所有内容组合在一起,您就可以得到

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

感谢你们所有人的帮助,你们真的帮了很多忙! - Lynton Grice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接