UPDATE according to TNTFreaks instructions answer.
I have a char variable data defined such as follow:
#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;
When the compiler check the serial_read
function, enter to this process is:
*Note: I type this serial_read
function only to illustration purposes in relation to workflow that follow my question in the process with respect to data
variable *
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;
}
When serial_read
function finish, data
is returned and have the char value like by example 1.86
I want to convert it that to float using atof()
such as I type the code section at the beginning code of my question and store the result on n1 variable
but the output that I get is:
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
The 1,000 value is the data
value which I get that is 1.86, but atof remove the decimal parts or not include the foat data.
In summary is possible that I am not passing of a well way the parameter to atof
function, (my n1
variable is float ).
With respect to sscanf
function, I am passing &n1 to sscanf like a a reference parameter to data to this be converted with atof
, but this doesn't works
I get the same result. I was thinking that is possible, although I understand the TNTFreaks instructions I am not apply it of a correct way?
what am I doing wrong?
First of all, char
is a type of variable that can only contain one or an array of characters not a string of characters. You may mean const char* data = "6.35"
which is a c style string and what the atof()
function requires as input. I would only use data
as a const char*
if you do not follow my recommendation below and still want to use sscanf()
instead of cin
.
In c++ using strings is easier than using const char*
or char arrays. I would declare data as a string, get the input, and then convert it into a const char*
using c_str()
so atof()
can use it.
atof
returns a double not a float so you should declare n1 as a double.
I recommend not using a mixture of c and c++ commands (i. e. cout
and sscanf()
). It will compile in c++ if the syntax is correct, but I think it will be easier for you to use cin
instead of sscanf()
.
You may also want to tell the compiler to assume the standard namespace (std) so you don't have to write std::
in front of all your cout
's, cin
's, endl
's, etc.
Example:
#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;
}
Updated, more intelligent, more useful answer:
These are just some things I took note of while doing some tests of my own.
n1 = sscanf(data, "%f", n1)
is not correct. It will compile, but the program should crash. (It did for me). First, sscanf()
does not return the float found in data. It returns the number of variables filled so it will not result in what you intend. Second, n1
needs to be made a reference parameter for this to work. You want to edit the original variable n1
not make a copy of it. Correct syntax would be: sscanf(data, "%f", &n1);
Example:
#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;
}