【问题标题】:How to concatenate char array elements and cast/convert them to float?如何连接 char 数组元素并将它们转换/转换为浮点数?
【发布时间】:2013-07-25 08:54:13
【问题描述】:

我正在使用 Winsock,我想将一些值从 Simulink 发送到我自己的程序,然后我将在我的数学方程式中使用这些值。我的电脑是 64 位的,所以一个 char 是 2 个字节,一个 float 是 8 个字节。我想在缓冲区中获取 3 个元素,以便将缓冲区声明为 char buffer[12]。现在我需要合并 buffer[0],buffer[1],buffer[2],buffer[3] 和 buffer[4],buffer[5],buffer[6],buffer[7] 等等并希望有一个像 12.23456 这样的值。我怎样才能做到这一点并将其转换(或转换)为浮点数,以便在我的数学方程式中使用该值?

这是我目前尝试过的:

#pragma once 
#pragma comment(lib, "Ws2_32.lib")
#include <Windows.h>
#include <WinSock.h>
#include <string.h>
#include <iostream>


using namespace std;
int main(){

    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2,2);
    int startup_RetVal = WSAStartup(DllVersion,&wsaData);

    SOCKET sSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    SOCKADDR_IN addr;

    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);

    bind(sSocket, (SOCKADDR*)&addr, sizeof(addr));
    char buf[12];

    recvfrom(sSocket,buf,sizeof(buf),NULL,NULL,NULL);

    char myString[4];
    strcpy(myString,buf[0]);
    strcat(myString,buf[1]);
    strcat(myString,buf[2]);
    strcat(myString,buf[3]);

    //cast it to float

    return 0;

}

此代码无法编译,因为它有关于字符串的错误。

【问题讨论】:

  • 一个语言标签是合适的。你可以确定你的不是世界上唯一的,也不是唯一可以使用winsock的。

标签: c++ casting concatenation winsock


【解决方案1】:

您的问题有些混乱。一个char占用1个字节,64位系统与否, float 占用 4 个字节。但是,您应该将浮点数的大小简单地表示为sizeof(float) 以避免不必要的假设。

您的 Windows PC 是一个 little-endian 系统,我假设 Simulink 将值作为 32 位 little-endian 浮点数传输到您的程序,因此无需担心 endian-conversion。 (但 检查 Simulink 设置,以防我对 32 位或小端序有误)。

我还假设正在传输这些值,这样您就可以指望一次收到 3 个, 随心所欲(尽管我不知道为什么您需要将它们捆绑在 3 秒中)。

在这种情况下,你的接收缓冲区,现在声明为char buf[12]; 应该被声明 如char buf[sizeof(float) * 3];

然后,删除:

char myString[4];
strcpy(myString,buf[0]);
strcat(myString,buf[1]);
strcat(myString,buf[2]);
strcat(myString,buf[3]);

//cast it to float

并将其替换为:

float af[3];
for (unsigned i = 0; i < 3; ++i) {
    memcpy(af + i,buf + (i * sizeof(float)),sizeof(float));
}

这会将buf中的3个连续浮点数复制到af[0]af[1]af[2]的3个浮点数中。阅读memcpyhere

这足以解决您的问题。但我强烈建议您检查 recvfrom 的返回值并采取相应措施。如果调用成功,它将 返回接收到的字节数为int;否则SOCKET_ERROR

您需要返回值为3 * sizeof(float),此代码才能正常工作。更灵活的代码 只需确保它是sizeof(float) 的倍数,然后提取尽可能多的浮点数。而且无论如何你都需要处理SOCKET_ERROR

至于您看到的与字符串相关的编译错误,它们是由于相同的错误造成的 在您的电话strcpy(myString,buf[0]) 和您的每个电话strcat(myString,buf[n]) 中。这 strcpy的签名是:

char * strcpy ( char * destination, const char * source );

strcat 是:

char * strcat ( char * destination, const char * source );

在每种情况下,第二个参数必须是const char *,并且在每种情况下,您都是 通过char。这就是编译器的错误信息告诉你的:

error C2664: 'strcpy' : cannot convert parameter 2 from 'char' to 'const char *'
error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'

【讨论】:

    【解决方案2】:

    使用 C++11,您可以通过这种方式轻松完成:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char buf[13] = "1.2378.40.00";
    
        for(int n=0; n<3; ++n){
            string s {buf[n*4],buf[n*4+1],buf[n*4+2],buf[n*4+3]};
            double value = stof(s);
            cout << value << endl;
        }
    }
    

    stof() 是自 C++11 以来的新功能。通过初始化列表对 s 进行初始化也是如此。

    【讨论】:

      猜你喜欢
      • 2021-07-16
      • 2011-02-28
      • 2013-03-23
      • 1970-01-01
      • 2017-10-24
      • 2019-01-06
      • 2020-09-02
      • 2016-09-01
      • 2021-10-27
      相关资源
      最近更新 更多