【问题标题】:Arduino sprintf float not formattingArduino sprintf float 未格式化
【发布时间】:2014-12-25 21:54:07
【问题描述】:

我有这个 arduino 草图,

char temperature[10];
float temp = 10.55;
sprintf(temperature,"%f F", temp);
Serial.println(temperature);

温度输出为

? F

关于如何格式化这个浮点数有什么想法吗?我需要它是一个字符字符串。

【问题讨论】:

    标签: c++ arduino printf


    【解决方案1】:

    由于某些性能原因,%f 未包含在 Arduino 的 sprintf() 实现中。更好的选择是使用dtostrf() - 您将浮点值转换为 C 风格的字符串,方法签名如下所示:

    char *dtostrf(double val, signed char width, unsigned char prec, char *s)
    

    使用此方法将其转换为C-Style字符串,然后使用sprintf,例如:

    char str_temp[6];
    
    /* 4 is mininum width, 2 is precision; float value is copied onto str_temp*/
    dtostrf(temp, 4, 2, str_temp);
    sprintf(temperature,"%s F", str_temp);
    

    您可以更改最小宽度和精度以匹配您要转换的浮点数。

    【讨论】:

    • 在我的情况下工作得很好。竖起大拇指!
    • 请注意,缓冲区的宽度:str_temp 在 6 个字符处非常紧凑
    【解决方案2】:

    如前所述,浮点支持不包含在 Arduino 上的 sprintf 中。

    字符串类

    Arduino 有自己的String 类。

    String value = String(3.14);
    

    那么,

    char *result = value.c_str();
    

    字符串类参考,以上链接

    构造 String 类的实例。有多个版本可以从不同的数据类型构造字符串(即将它们格式化为字符序列),包括:

    • 双引号中的常量字符串(即 char 数组)
    • 单引号中的单个常量字符
    • String 对象的另一个实例
    • 常量整数或长整数
    • 使用指定基数的常量整数或长整数
    • 整数或长整数变量
    • 整数或长整数变量,使用指定的基数
    • 浮点数或双精度数,使用指定的小数位

    【讨论】:

    • 对上面指针的重要提示:“当你修改String对象,或者当它被销毁时,之前c_str()返回的任何指针都变得无效,不能再使用了。”跨度>
    • 我会说,很明显,但是是的,这对于刚接触 Arduino 编程的人来说是一个很好的观点。
    • Arduino 的 String 类没有接受 float 或 double 的方法。这只有效,因为它将它转换为整数。
    • @CameronLowellPalmer 你是对的,我的错。最新的 Arduino 版本确实包括对 double 和 float 的 String 支持。我正在使用 Ubuntu 中包含的旧版本,该版本早于这个版本,当我尝试将浮点数传递给 String() 时会引发编译器错误。
    • 它甚至将第二个参数作为精度,String(3.1434, 4)
    【解决方案3】:

    我已经努力了几个小时才能做到这一点,但我终于做到了。这使用了 Platformio 提供的现代 Espressif C++,我的目标 MCU 是 ESP32。

    我想显示一个前缀标签,float/int 值,然后是单位,全​​部内联。

    由于我使用的是 OLED 显示器,因此我无法转达单独的 Serial.print() 语句。

    这是我的代码示例:

      int strLenLight = sizeof("Light ADC: 0000");
      int strLenTemp = sizeof("Temp: 000.0 °C");
      int strLenHumd = sizeof("Humd: 00.0 %");
    
      char displayLight[strLenLight] = "Light ADC: ";
      char displayTemp[strLenTemp] = "Temp: ";
      char displayHumd[strLenHumd] = "Humd: ";
    
      snprintf(strchr(displayLight, '\0'), sizeof(displayLight), "%d", light_value);
      snprintf(strchr(displayTemp, '\0'), sizeof(displayTemp), "%.1f °C", temperature); 
      snprintf(strchr(displayHumd, '\0'), sizeof(displayHumd), "%.1f %%", humidity); 
    
      Serial.println(displayLight);
      Serial.println(displayTemp);
      Serial.println(displayHumd);
    

    其中显示:

    Light ADC: 1777
    Temp: 25.4 °C
    Humd: 55.0 %
    

    【讨论】:

      【解决方案4】:

      dtostrf() 已弃用,并且并非在每个板核心平台上都存在。 另一方面,sprintf() 在 AVR 平台上不格式化浮点数!

      【讨论】:

      • 默认链接的sprintf()不支持%f,但如果需要,您可以链接完整版的sprintf()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      相关资源
      最近更新 更多