【问题标题】:sprintf not giving expected valuessprintf 没有给出预期值
【发布时间】:2023-03-07 00:48:01
【问题描述】:

我有一个用十六进制数字填充的数组 (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 多行代码,所以我提供的应该足以编译和运行。

【问题讨论】:

  • server0-3是如何初始化的?看起来像指向堆栈分配的单个字符而不是缓冲区的指针......?
  • serverx 变量声明是问题的关键。不要将它们排除在您发布的代码之外。事实上,发布一个完整的程序有什么难的,我们需要做的就是在我们的代码编辑器中复制/粘贴并运行它?
  • 请发一个SSCCE,可以按原样复制/粘贴和编译。
  • 我将编辑我的问题以包含 serverx 的声明以及 SSCCE

标签: c printf hex type-conversion bitconverter


【解决方案1】:

当你这样做时:

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]);

【讨论】:

  • 如果只使用sprintf,缓冲区不仅应该“足够大”,而且比预期的要大。太多的程序员偷工减料,试图预测,精确到字节,他们的缓冲区有多大。这几乎总是会导致内存覆盖。
  • 好吧,我刚刚尝试了 snprintf() 并使用了您在上面演示的语法。当我将 server0[0] 的 printf 作为 %s 执行时,控制台会打印垃圾。我期待 server0[0] = '4' 和 server0[1] = 'A'
  • 不要做printf("%s", server0[0]);,因为那是UB。你想做printf("%s", server0);
  • 我最终采纳了您的第一个建议 - 创建一个足够大的缓冲区并使用 sprintf 进行转换。它成功了。谢谢大佬。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多