C sprintf未给出预期值

C sprintf未给出预期值,c,printf,hex,type-conversion,bitconverter,C,Printf,Hex,Type Conversion,Bitconverter,我有一个数组(readingreg[4]),它用十六进制数字填充。我的目标是将数据类型转换为字符串。我读了一些建议,似乎sprintf是一条出路 这就是我所尝试的: sprintf(server0, "0x%02X", readingreg[0]); printf("This is element 0: %s\n", server0); sprintf(server1, "0x%02X", readingreg[1]); printf("This is element 1: %s\n", se

我有一个数组(readingreg[4]),它用十六进制数字填充。我的目标是将数据类型转换为字符串。我读了一些建议,似乎sprintf是一条出路

这就是我所尝试的:

sprintf(server0, "0x%02X", readingreg[0]);
printf("This is element 0: %s\n", server0);

sprintf(server1, "0x%02X", readingreg[1]);
printf("This is element 1: %s\n", server1);

sprintf(server2, "0x%02X", readingreg[2]);
printf("This is element 2: %s\n", server2);

sprintf(server3, "0x%02X", readingreg[3]);
printf("This is element 3: %s\n", server3);


printf("This is element 0: %s\n", server0);
printf("This is element 1: %s\n", server1);
printf("This is element 2: %s\n", server2);
printf("This is element 3: %s\n", server3);
以下是我的输出:

This is element 0: 0x4A
This is element 1: 0xAA
This is element 2: 0xAA
This is element 3: 0xA0
This is element 0: 0
This is element 1: A0
This is element 2: xA0
This is element 3: 0xA0
在这一点上,我很困惑sprintf为我做了什么。我的预期输出是server0-server4都保留其字符串值。你知道为什么会这样吗

以下是该程序的简化版本:

readingreg[0] = 4A;
readingreg[1] = AA;
readingreg[2] = AA;
readingreg[3] = A0;
char server0[1];
char server1[1];
char server2[1];
char server3[1];
整个程序有1000多行代码,所以我提供的应该足以编译和运行

当您这样做时:

char server0[1];
sprintf(server0, "0x%02X", readingreg[0]);
您正试图将5个字符(不要忘记尾随“\0”)放入1个字符的缓冲区。这会导致未定义的行为,而这些行为恰好在观察到的输出中显示出来

您应该(至少)使字符缓冲区足够大,以存储您放入其中的任何内容:

char server0[8];
sprintf(server0, "0x%02X", readingreg[0]);
更好的解决方案是将数组变大,并使用
snprintf()
或类似函数确保不会溢出字符缓冲区:

char server0[8];
snprintf (server0, sizeof(server0)/sizeof(server0[0]), "0x%02X", readingreg[0]);

服务器0-3是如何初始化的?看起来像是指向堆栈分配的单个字符而不是缓冲区的指针…?
serverx
变量声明是问题的关键。不要在你发布的代码中遗漏它们。事实上,发布一个完整的程序有什么困难,我们需要做的就是在我们的代码编辑器中复制/粘贴并运行它?请发布一个可以复制/粘贴并按原样编译的程序。我将编辑我的问题,以包括serverx的声明和SSCCEIf,只需使用
sprintf
,而不仅仅是缓冲区“刚好足够大”,但比预期的要大。太多的程序员抄近路,试图预测他们的缓冲区到底有多大。这几乎总是会导致内存覆盖。好吧,我只是尝试了snprintf(),并使用了上面演示的语法。当我对服务器0[0]执行printf时作为%s,控制台打印垃圾。我希望server0[0]='4'和server0[1]='A'不要做
printf(“%s”,server0[0]);
这就是UB。你想做
printf(“%s”,server0”);
。我最终同意了你的第一个建议——创建一个足够大的缓冲区并使用sprintf进行转换。成功了。谢谢你。