将 char[] 转换为 float 或 double - C++
Converting char[] to float or double - c++
根据 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] = '[=11=]';
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
变量是 float )。
关于 sscanf
函数,我将 &n1 传递给 sscanf,就像数据的参考参数一样,要用 atof
转换,但这不起作用
我得到了同样的结果。
我认为这是可能的,虽然我理解 TNTFreaks 说明,但我没有以正确的方式应用它?
我做错了什么?
首先,char
是一种变量类型,只能包含一个或一个字符数组,不能包含一串字符。你可能指的是 const char* data = "6.35"
这是一个 c 风格的字符串,atof()
函数需要什么作为输入。如果您不遵循我下面的建议并且仍然想使用 sscanf()
而不是 cin
,我只会将 data
用作 const char*
。
在 C++ 中,使用字符串比使用 const char*
或字符数组更容易。我会将数据声明为字符串,获取输入,然后使用 c_str()
将其转换为 const char*
,以便 atof()
可以使用它。
atof
returns 是 double 而不是 float,所以你应该将 n1 声明为 double。
我建议不要混合使用 c 和 c++ 命令(即 cout
和 sscanf()
)。如果语法正确,它将在 c++ 中编译,但我认为使用 cin
而不是 sscanf()
.
会更容易
您可能还想告诉编译器采用标准命名空间 (std),这样您就不必在所有 cout
前面写 std::
,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;
}
更新,更智能,更有用的答案:
这些只是我自己做一些测试时注意到的一些事情。
- 不要用double,用float。 Double 在我的研究中不起作用。
- 当你使用 %.3f 时,你显示的是整数的小数点后 3 位,因此你得到 6.000
n1 = sscanf(data, "%f", n1)
不正确。它会编译,但程序应该会崩溃。 (它对我有用)。首先,sscanf()
不会 return 在数据中找到的浮点数。它 return 是填充的变量数,因此不会产生您想要的结果。其次,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;
}
根据 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] = '[=11=]';
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
变量是 float )。
关于 sscanf
函数,我将 &n1 传递给 sscanf,就像数据的参考参数一样,要用 atof
转换,但这不起作用
我得到了同样的结果。 我认为这是可能的,虽然我理解 TNTFreaks 说明,但我没有以正确的方式应用它?
我做错了什么?
首先,char
是一种变量类型,只能包含一个或一个字符数组,不能包含一串字符。你可能指的是 const char* data = "6.35"
这是一个 c 风格的字符串,atof()
函数需要什么作为输入。如果您不遵循我下面的建议并且仍然想使用 sscanf()
而不是 cin
,我只会将 data
用作 const char*
。
在 C++ 中,使用字符串比使用 const char*
或字符数组更容易。我会将数据声明为字符串,获取输入,然后使用 c_str()
将其转换为 const char*
,以便 atof()
可以使用它。
atof
returns 是 double 而不是 float,所以你应该将 n1 声明为 double。
我建议不要混合使用 c 和 c++ 命令(即 cout
和 sscanf()
)。如果语法正确,它将在 c++ 中编译,但我认为使用 cin
而不是 sscanf()
.
您可能还想告诉编译器采用标准命名空间 (std),这样您就不必在所有 cout
前面写 std::
,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;
}
更新,更智能,更有用的答案:
这些只是我自己做一些测试时注意到的一些事情。
- 不要用double,用float。 Double 在我的研究中不起作用。
- 当你使用 %.3f 时,你显示的是整数的小数点后 3 位,因此你得到 6.000
n1 = sscanf(data, "%f", n1)
不正确。它会编译,但程序应该会崩溃。 (它对我有用)。首先,sscanf()
不会 return 在数据中找到的浮点数。它 return 是填充的变量数,因此不会产生您想要的结果。其次,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;
}