将char []转换为float或double - c ++

bga*_*ial -1 c++ type-conversion atof

根据 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;
Run Code Online (Sandbox Code Playgroud)

当编译器检查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;

}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

1,000值是data我得到的值1.86,但是除去小数部分或不包括foat数据.

总而言之,我可能没有将参数传递给atof函数,(我的n1变量是float).关于sscanf功能,我传递&n1到sscanf就像一个参考参数到数据转换为atof,但这不起作用

我得到了相同的结果.我认为这是可能的,虽然我理解TNTFreaks说明我不是以正确的方式应用它?

我究竟做错了什么?

TNT*_*aks 7

首先,char是一种变量,它只能包含一个或一个字符数组而不是一串字符.您可能意味着const char* data = "6.35"哪个是ac样式字符串以及atof()函数需要作为输入.我只是将使用data一个const char*,如果你不按照我的建议之下,仍然要使用sscanf()替代cin.

在c ++中使用字符串比使用const char*或char数组更容易.我会将数据声明为字符串,获取输入,然后将其转换为const char*使用,c_str()因此atof()可以使用它.

atof 返回double而不是float,因此您应该将n1声明为double.

我建议不要混合使用c和c ++命令(即coutsscanf()).如果语法正确,它将在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;
}
Run Code Online (Sandbox Code Playgroud)

更新,更智能,更有用的答案:

这些只是我在做自己的一些测试时注意到的一些事情.

  1. 不要使用double,请使用float.Double在我的研究中没有用.
  2. 当你使用%.3f时,你显示整数的3个小数位,这就是为什么你得到6.000
  3. n1 = sscanf(data, "%f", n1)是不正确的.它会编译,但程序应该崩溃.(它对我有用).首先,sscanf()不返回在数据中找到的float.它返回填充的变量数,因此不会产生您想要的结果.其次,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;
}
Run Code Online (Sandbox Code Playgroud)