【问题标题】:Confused about dtostrf function对 dtostrf 函数感到困惑
【发布时间】:2018-01-09 14:31:28
【问题描述】:

我目前正在从事个人 AVR 项目,并编写了一个使用 UART 将双精度数据传输到我的串行 LCD 屏幕的函数。为此,我将 double 转换为 char 数组,然后逐个字符地串行传输它。

让我感到困惑的是 char 缓冲区数组的长度必须是多少。数组的长度似乎与 double 的大小不对应。有趣的是,我可以将数组的长度设置为 0,它仍然可以工作,如下所示:

    void USART_Transmit_Double(double doubleNumber) {

    char aNumberAsString[0];
    dtostrf(doubleNumber, 3, 0, aNumberAsString);

    USART_Transmit_String(aNumberAsString);
}

在这里,我在主循环中打印数字 1234,它在我的 LCD 上显示得很好。但是,如果我将精度更改为 1,那么整个事情就会变得混乱。

我在我的 Arduino 上测试了相同的函数并不断得到完全不同的结果,每个字符似乎对应于数组的每个元素,所以如果我想打印 1234.2,我必须将缓冲区长度设置为 6 .

那么这里发生了什么?

【问题讨论】:

  • 你能把显示的代码段here直接放到帖子里吗?在您的其他内容的上下文中会更容易看到。
  • 关于 ...要打印 1234.2,我必须将缓冲区长度设置为 6。:需要包含字符串 1234.2 的缓冲区需要有空间7个字符。 C string 是一个以 NULL 字符结尾的字符数组。
  • @ryyker 虽然我没有使用字符串,但我正在遍历一个字符数组并通过串行传输一个字符一个字符。更奇怪的是,它适用于长度为 0 的缓冲区。
  • 欢迎来到未定义行为的世界
  • @ryyker "需要包含字符串 1234.2 的缓冲区需要有 7 个字符的空间",没错。但现在我更加困惑,因为我尝试了使用整数和 itoa 的相同过程函数,它是一对一的映射,例如,要显示 255,我需要缓冲区长度为 1。

标签: c arduino char double avr


【解决方案1】:

你遇到了undefined behavior。特别是,在此链接中,短语:未定义行为的示例是数组边界之外的内存访问,... 可能适用于您所描述的场景。如果您尝试访问(但不拥有)的内存没有碰巧违反另一个变量的内存空间,它可能会工作一千次。第一次这样做时,您的程序将崩溃。

以下语句虽然合法,但会创建一个无用的变量,这可能是您看到奇怪结果的原因:

char aNumberAsString[0];

处理您的评论
您可能会将创建包含单个值的缓冲区所需的索引值与创建变量后访问该值所需的索引值混淆。即

char aNumberAsString[1] = 'A'; //creates an array of 1 char ([1])

将创建一个可以包含单个 char 值的变量。

char value = aNumberAsString[0]; // accesses the only value in array ([0])

示例:
查看如何使用dtostrf 函数的示例here
请注意此示例使用的变量的大小:

static float f_val = 123.6794;
static char outstr[15];

支持以下调用:

 dtostrf(f_val,7, 3, outstr);

产生以下输出:

123.679

【讨论】:

  • 解决您评论的第二部分 - 不,我声明了一个长度为 0 的新 char 数组。
  • @Hypomania - 是的,这就是问题所在。长度 == 0 的数组是无用的。要么创建一个简单的 char 变量,要么创建一个 char 数组,其中包含至少 1 个值的空间。
  • 有道理,但无论如何都没有区别。我的自定义板上的字符数和缓冲区长度之间没有直接关系(在 Arduino 上工作正常)。
  • @Hypomania - 你没有得到它。如果您使用零长度数组来传递单个 char 值,那么您正在调用未定义的行为。它可能看起来要进行数百次迭代,然后突然间,没有明显的原因,您的程序将崩溃。它现在在什么系统上运行并不重要。听听 Kevin 制作的 cmets,然后重新阅读我的帖子。两者都提供了很好的建议,即使现在没有意义。
  • @Hypomania - 你至少同意char aNumberAsString[0];虽然是法律声明,但没用吗?
猜你喜欢
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多