如何将无符号字符数组存储为浮点值?

Posted

技术标签:

【中文标题】如何将无符号字符数组存储为浮点值?【英文标题】:How to store a unsigned char array to float value? 【发布时间】:2019-05-07 06:30:42 【问题描述】:

我正在尝试使用 RS232 串行通信从 Arduino 和 Raspberry Pi 获取传感器数据。我已经搜索了这个小东西,并在下面的链接中找到了一些相关的东西,但无法得到完整的想法。

操作系统(内核)有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且串行端口上有新字符到达,则缓冲区中最旧的字符将被覆盖,因此将丢失。成功调用 RS232_OpenComport() 后,操作系统将开始缓冲传入的字符。

这些值正确地从 Arduino 传到 Raspberry Pi(输出附在下面),它存储在指向 unsigned char[] 的指针中,该指针定义为 unsigned char *buf[4096]。

int main()

  int i, n,
      cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
      bdrate=9600;       /* 9600 baud */

  unsigned char buf[4096];

  char mode[]='8','N','1',0;

  while(1)
  
    n = RS232_PollComport(cport_nr, buf, 4095);

    if(n > 0)
    
      buf[n] = 0;

      for(i=0; i < n; i++)
      
        if(buf[i] < 32)  /* replace unreadable control-codes by dots */
        
          buf[i] = '.';
        
      

      printf("received %i bytes: %s\n", n, (char *)buf);
    

现在我想将这些值存储在另一个浮点/双精度变量中,以便我可以对其执行进一步的操作。如何存储一个值假设 0.01 到一个浮点数/双精度数,稍后用于创建东西。

【问题讨论】:

尝试在 cppreference.com 或 cplusplus.com 上查找 atof/atod/strtod 在这里回答:***.com/questions/1012571/… 如果您的数据包含多个数字,您只需先将数字分开即可。 @Ptaq666 你能详细说明一下吗,我不知道到底是什么。 std::string to float or double的可能重复 @uvan ,在答案中详细说明。现在明白了吗? 【参考方案1】:

从屏幕截图中的输出看来,您发送的是数字的字符串表示形式,而不是实际数字。您只需要检测那些刚刚用. 替换的“不可读控制代码”,因为它们可能会告诉您一个数字何时结束而另一个数字何时开始。只需让QSerialPort * serial; 成为适当的班级成员。

另外,检查打开端口时的错误:serial-&gt;open(QIODevice::ReadWrite); 然后,在serialreceived() 中插入一些qDebug() 以查看是否调用了插槽以及canReadLine() 是否有效。您应该使用QByteArray 来读取您的数据。如果响应中有任何不符合字符串的字符,则生成的QString 将被提前终止,请使用readLine() 而不是readAll(),如下所示:

QByteArray data = serial -> readLine();
qDebug() < data.toHex(' '); // prints the hex representation of your char array
QString str(data);
qDebug() << str;

【讨论】:

【参考方案2】:

首先,最好使用其他 ASCII 字符(例如空格)来分隔数字,因为. dot 是浮点数的一部分。然后,您可以从原始unsigned char 数组构造std::string 对象,将其拆分为多个字符串并将每个string 转换为float

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

int main() 
    // imagine that this buff is already after read and preprocessing
    unsigned char buff[1024] = "13.60  13.60  -11.12  -0.3  and let's say that the rest is garbage";
    int n = 28;  // let's say that you received 28 bytes
    std::string strBuff(reinterpret_cast<char*>(buff), n); // construct a string from buff using just first 28 bytes
    std::vector<std::string> numbers;
    boost::split(numbers, strBuff, boost::is_any_of(" "), boost::token_compress_on);
    for (const auto& n : numbers) 
        try 
            std::cout << std::stof(n) << std::endl;
         catch (const std::exception& e) 
            std::cout << n << " is not convertible to float: " << e.what() << std::endl;
        
    
    return 0;

我采用了this answer 的字符串拆分方法,但你可以使用任何适合你的方法。

我使用reinterpret_cast 是因为std::string 接受char 而不是unsigned char 作为CTor arg。

【讨论】:

它是用于无符号字符缓冲区的,但我已经采取了(Buf 是一个指向缓冲区的指针,并且大小缓冲区的大小以字节为单位)。在这种情况下,我该如何转换?将接收到的字符数返回到缓冲区中。

以上是关于如何将无符号字符数组存储为浮点值?的主要内容,如果未能解决你的问题,请参考以下文章

如何将无符号字符数组解析为数值数据

创建 Java 实用函数以将无符号字符数组转换为字符串

将无符号字符读入字符串

如何在C中将无符号字符数组转换为十六进制字符串

将无符号字符数组返回到主函数

将无符号字符附加到向量会更改其值