如何将无符号字符数组存储为浮点值?
How to store a unsigned char array to float value?
我正在尝试使用 RS232 串行通信从 Arduino & Raspberry Pi 获取传感器数据。我搜索了这个小东西,并在下面 link 找到了与此相关的东西,但无法得到完整的想法。
os(内核)有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且新字符到达串行端口,则缓冲区中最旧的字符将被覆盖,因此将为 lost。成功调用 RS232_OpenComport() 后,os 将开始缓冲传入字符。
这些值正确地从 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);
}
}
现在我想将这些值存储在另一个 float/double 变量中,以便我可以对其执行进一步的操作。如何将值 suppose 0.01
存储到 float/double 中,稍后用于创建内容。
首先,如果使用其他ASCII字符(例如space)来分隔数字会更好,因为.
点是浮点数的一部分。然后,您可以从原始 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。
从屏幕截图的输出来看,您发送的似乎是数字的字符串表示形式,而不是实际数字。你只需要检测那些你刚用 .
替换的 "unreadable control-codes",因为它们可能会告诉你一个数字何时结束,另一个数字何时开始。只需让 QSerialPort * serial;
成为合适的 class 成员即可。
此外,检查打开端口时是否有错误:serial->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;
我正在尝试使用 RS232 串行通信从 Arduino & Raspberry Pi 获取传感器数据。我搜索了这个小东西,并在下面 link 找到了与此相关的东西,但无法得到完整的想法。
os(内核)有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且新字符到达串行端口,则缓冲区中最旧的字符将被覆盖,因此将为 lost。成功调用 RS232_OpenComport() 后,os 将开始缓冲传入字符。
这些值正确地从 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);
}
}
现在我想将这些值存储在另一个 float/double 变量中,以便我可以对其执行进一步的操作。如何将值 suppose 0.01
存储到 float/double 中,稍后用于创建内容。
首先,如果使用其他ASCII字符(例如space)来分隔数字会更好,因为.
点是浮点数的一部分。然后,您可以从原始 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。
从屏幕截图的输出来看,您发送的似乎是数字的字符串表示形式,而不是实际数字。你只需要检测那些你刚用 .
替换的 "unreadable control-codes",因为它们可能会告诉你一个数字何时结束,另一个数字何时开始。只需让 QSerialPort * serial;
成为合适的 class 成员即可。
此外,检查打开端口时是否有错误:serial->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;