C语言 使用 printf 以十六进制格式打印字符串,结果失真
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15823597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
use printf to print character string in hex format, distorted results
提问by misteryes
I want to print character string in hex format,
我想以十六进制格式打印字符串,
on machine A , something like
在机器 A 上,类似
ori_mesg = gen_rdm_bytestream (1400,seed)
sendto(machine B, ori_mesg, len(mesg))
on machine B
在机器 B 上
recvfrom(machine A, mesg)
mesg_check = gen_rdm_bytestream (1400, seed)
for(i=0;i<20;i++){
printf("%02x ", *(mesg+i)& 0xFF);
}
printf("\n");
for(i=0;i<20;i++){
printf("%02x ", *(mesg_check+i));
}
printf("\n");
seedvaries among 1, 2 3....
seed1, 2 3 ....
the bytes generation funcion is:
字节生成函数是:
u_char *gen_rdm_bytestream (size_t num_bytes, unsigned int seed)
{
u_char *stream = malloc (num_bytes+4);
size_t i;
u_int16_t seq = seed;
seq = htons(seq);
u_int16_t tail = num_bytes;
tail = htons(tail);
memcpy(stream, &seq, sizeof(seq));
srand(seed);
for (i = 3; i < num_bytes+2; i++){
stream[i] = rand ();
}
memcpy(stream+num_bytes+2, &tail, sizeof(tail));
return stream;
}
but I got results from printf like:
但我从 printf 得到的结果如下:
00 01 00 67 c6 69 73 51 ff 4a ec 29 cd ba ab f2 fb e3 46 7c
00 01 00 67 ffffffc6 69 73 51 ffffffff 4a ffffffec 29 ffffffcd ffffffba ffffffab fffffff2 fffffffb ffffffe3 46 7c
or
或者
00 02 88 fa 7f 44 4f d5 d2 00 2d 29 4b 96 c3 4d c5 7d 29 7e
00 02 00 fffffffa 7f 44 4f ffffffd5 ffffffd2 00 2d 29 4b ffffff96 ffffffc3 4d ffffffc5 7d 29 7e
why are there so many ffffffor mesg_check?
为什么有这么多fffff的mesg_check?
are there any potential reasons for this phenomenon? thanks!
这种现象是否有任何潜在原因?谢谢!
回答by Keith Thompson
Here's a small program that illustrates the problem I thinkyou might be having:
这是一个小程序,说明了我认为您可能遇到的问题:
#include <stdio.h>
int main(void) {
char arr[] = { 0, 16, 127, 128, 255 };
for (int i = 0; i < sizeof arr; i ++) {
printf(" %2x", arr[i]);
}
putchar('\n');
return 0;
}
On my system (on which plain charis signed), I get this output:
在我的系统上(在该系统上char签名),我得到以下输出:
0 10 7f ffffff80 ffffffff
The value 255, when stored in a (signed) char, is stored as -1. In the printfcall, it's promoted to (signed) int-- but the "%2x"format tells printfto treat it as an unsigned int, so it displays fffffffff.
值255存储在 (signed) 中时char,存储为-1。在printf调用中,它被提升为 (signed) int- 但"%2x"格式告诉printf将其视为unsigned int,因此它显示fffffffff.
Make sure that your mesgand mesg_checkarrays are defined as arrays of unsigned char, not plain char.
确保您的mesg和mesg_check数组被定义为 的数组unsigned char,而不是普通的char。
UPDATE:Rereading this answer more than a year later, I realize it's not quite correct. Here's a program that works correctly on my system, and will almost certainly work on any reasonable system:
更新:一年多后重读这个答案,我意识到它不太正确。这是一个可以在我的系统上正常运行的程序,并且几乎肯定可以在任何合理的系统上运行:
#include <stdio.h>
int main(void) {
unsigned char arr[] = { 0, 16, 127, 128, 255 };
for (int i = 0; i < sizeof arr; i ++) {
printf(" %02x", arr[i]);
}
putchar('\n');
return 0;
}
The output is:
输出是:
00 10 7f 80 ff
An argument of type unsigned charis promoted to (signed) int(assuming that intcan hold all values of type unsigned char, i.e., INT_MAX >= UCHAR_MAX, which is the case on practically all systems). So the argument arr[i]is promoted to int, while the " %02x"format requires an argument of type unsigned int.
type 的参数unsigned char被提升为 (signed) int(假设它int可以保存所有 type 的值unsigned char,即 ,INT_MAX >= UCHAR_MAX实际上在所有系统上都是这种情况)。因此参数arr[i]被提升为int,而" %02x"格式需要一个类型为 的参数unsigned int。
The C standard strongly implies, but doesn't quitestate directly, that arguments of corresponding signed and unsigned types are interchangeable as long as they're within the range of both types -- which is the case here.
C标准强烈暗示,但不会很直接的状态,对应符号和无符号类型的论点是,只要它们是两种类型的范围内互换-这是这里的情况。
To be completelycorrect, you need to ensure that the argument is actually of type unsigned int:
为了完全正确,您需要确保参数实际上是类型unsigned int:
printf("%02x", (unsigned)arr[i]);
回答by Akash kumar
Yup, always print string in hex format as:
是的,总是以十六进制格式打印字符串为:
for(i=0;till string length;i++)
printf("%02X",(unsigned char)str[i]);
you will get error when you try to print
尝试打印时会出错
the whole string in one go and when printing Hex string character by character which using 'Unsigned char' if the string is in format other than 'Unsigned char'
一次打印整个字符串,如果字符串的格式不是“无符号字符”,则在逐个字符打印十六进制字符串时使用“无符号字符”

