根据 TNTFreaks说明更新更新。
我有一个char变量数据定义如下:
#define CMD_LEN 4
char data[CMD_LEN + 1];
float n1;
# I pass the data variable to `serial_read` function
n = serial_read(serial_fd, data, CMD_LEN, TIMEOUT);
# Here, the process goes to serial_read function more below and
# after it return here again to follow ...
std::cout << "Data brought from serial_read method " << data << std::endl;
flush = tcflush(serial_fd, TCIOFLUSH);
//n = n*0.01f;
cout << "Applying sscanf " << std::endl;
sscanf(data, "%f", &n1);
printf("%.3f" "%s", n1, " ");
n1 = atof(data) * 0.5f;
printf("%.3f", n1);
cout << "n1 value which have data turn it " << n1 << std::endl;
当编译器检查serial_read
函数时,输入到此过程是:
*注意:我输入此serial_read
功能仅用于与data
变量*
int SerialDriver::serial_read(int serial_fd, char *data, int size, int timeout_usec)
{
std::cout << "Enter to serial_read method " << std::endl;
fd_set fds;
struct timeval timeout;
bool band = false;
int count = 0;
int ret;
int n;
//-- Wait for the data. A block of size bytes is expected to arrive
//-- within the timeout_usec time. This block can be received as
//-- smaller blocks.
do
{
//-- Set the fds variable to wait for the serial descriptor
FD_ZERO(&fds);
FD_SET(serial_fd, &fds);
//-- Set the timeout in usec.
timeout.tv_sec = 0;
timeout.tv_usec = timeout_usec;
// std::cout << "timeouts establecidos " << std::endl;
//-- Wait for the data
ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
//-- If there are data waiting: read it
if (ret == 1)
{
//-- Read the data (n bytes)
n = read(serial_fd, &data[count], 1);
// read viene de sofa/src/applications/plugins/SofaPML/argumentParser.h
std::cout << "Enter to read method to read hapkit data via serial port " << std::endl;
if (band)
{
if (data[count] != ' ')
{
if (data[count] == '\n')
{
data[count] = '\0';
return count;
}
//-- The number of bytes receives is increased in n
count += n;
}
}
if (!band && data[count] == '\n')
{
band = true;
}
//-- The last byte is always a 0 (for printing the string data)
data[count] = 0;
}
std::cout << "band value: " << band << " and data: " << data << std::endl;
//-- Repeat the loop until a data block of size bytes is received or
//-- a timeout occurs
} while (count < size && ret == 1);
//-- Return the number of bytes reads. 0 If a timeout has occurred.
std::cout << "Leaving serial_read method " << std::endl;
std::cout << "count value " << count << std::endl;
return count;
}
当serial_read
函数完成时,返回data
并具有char值,如示例1.86
我想将它转换为使用atof()
浮动,例如我在我的问题的开头代码中键入代码部分并将结果存储在n1变量上
但我得到的输出是:
Data brought from serial_read method 1.86
Applying sscanf
1,000 0,500n1 value which have data turn it 0.5
Serial Driver draw n1: 0.5 1
1,000
1,000值是我得到的data
值1.86,但是除去小数部分或不包括foat数据。
总之,我可能没有将参数传递给atof
函数,(我的n1
变量是浮点数)。
关于sscanf
函数,我将&amp; n1传递给sscanf,就像数据的参考参数一样,用atof
进行转换,但这不起作用
我得到了相同的结果。 我认为这是可能的,虽然我理解TNTFreaks说明我不是以正确的方式应用它?
我做错了什么?答案 0 :(得分:7)
首先,char
是一种变量,只能包含一个或一个字符数组而不是一个字符串。您可以将const char* data = "6.35"
表示为c样式字符串以及atof()
函数需要作为输入的内容。如果您不遵循我的建议,我只会将data
用作const char*
,但仍然希望使用sscanf()
代替cin
。
在c ++中使用字符串比使用const char*
或char数组更容易。我会将数据声明为字符串,获取输入,然后使用const char*
将其转换为c_str()
,以便atof()
可以使用它。
atof
返回一个double而不是float,因此你应该将n1声明为double。
我建议不要混合使用c和c ++命令(即cout
和sscanf()
)。如果语法正确,它将用c ++编译,但我认为使用cin
而不是sscanf()
会更容易。
您可能还想告诉编译器采用标准命名空间(std),这样您就不必在std::
所有cout
之前写cin
endl
的,#include <cstdlib> //atof
#include <iostream> //cout, cin, endl
#include <string> //string, c_str()
using namespace std; //now you don't have to write std::cout
int main() {
float n1;
string data;
cin >> data; //get input
n1 = atof(data.c_str()); //convert data to const char* and make it a float
cout << "Original data: " << data << endl; //output
cout << "Result: " << n1;
}
等等。
示例:
n1 = sscanf(data, "%f", n1)
更新,更智能,更实用的答案:
这些只是我在做自己的一些测试时注意到的一些事情。
sscanf()
不正确。它会编译,但程序应该崩溃。 (它对我有用)。首先,n1
不返回数据中找到的浮点数。它返回填充的变量数,因此不会产生您想要的结果。其次,n1
需要成为参考参数才能实现。您想要编辑原始变量sscanf(data, "%f", &n1);
,而不是复制它。正确的语法是:#include <cstdlib>
#include <cstdio>
using namespace std;
int main() {
char data[5] = "6.35";
float n1;
sscanf(data, "%f", &n1);
printf("%.3f" "%s", n1, " ");
n1 = atof(data);
printf("%.3f", n1);
return 0;
}
示例:
#include "SpinLock.h"
#include <iostream>
using namespace LockFree;
using namespace std;
void tSpinWait::Lock(tSpinLock &LockObj)
{
m_iterations = 0;
while(true)
{
// A thread alreading owning the lock shouldn't be allowed to wait to acquire the lock - reentrant safe
if(LockObj.dest == GetCurrentThreadId())
break;
/*
Spinning in a loop of interlockedxxx calls can reduce the available memory bandwidth and slow
down the rest of the system. Interlocked calls are expensive in their use of the system memory
bus. It is better to see if the 'dest' value is what it is expected and then retry interlockedxx.
*/
if(InterlockedCompareExchange(&LockObj.dest, LockObj.exchange, LockObj.compare) == 0)
{
//assign CurrentThreadId to dest to make it re-entrant safe
LockObj.dest = GetCurrentThreadId();
// lock acquired
break;
}
// spin wait to acquire
while(LockObj.dest != LockObj.compare)
{
if(HasThreasholdReached())
{
if(m_iterations + YIELD_ITERATION >= MAX_SLEEP_ITERATION)
Sleep(0);
if(m_iterations >= YIELD_ITERATION && m_iterations < MAX_SLEEP_ITERATION)
{
m_iterations = 0;
SwitchToThread();
}
}
// Yield processor on multi-processor but if on single processor then give other thread the CPU
m_iterations++;
if(Helper::GetNumberOfProcessors() > 1) { YieldProcessor(/*no op*/); }
else { SwitchToThread(); }
}
}
}
//
void tSpinWait::Unlock(tSpinLock &LockObj)
{
if(LockObj.dest != GetCurrentThreadId())
throw std::runtime_error("Unexpected thread-id in release");
// lock released
InterlockedCompareExchange(&LockObj.dest, LockObj.compare, GetCurrentThreadId());
}