0

我正在使用 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;

}

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

4

2 回答 2

1

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

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

我还假设正在传输这些值,这样您就可以按自己的意愿一次接收 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));
}

这会将 3 个连续的浮点数从 3 个浮点数复制bufaf[0], af[1], af[2]memcpy 在这里阅读。

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

您需要返回值才能3 * sizeof(float)使此代码正常工作。更灵活的代码只会确保它是的倍数,sizeof(float)然后提取尽可能多的浮点数。并且在任何情况下您都需要处理SOCKET_ERROR.

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

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

strcat是:

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

在每种情况下,第二个参数必须是 aconst char *并且在每种情况下您都传递了 a 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 *'
于 2013-07-25T14:11:12.043 回答
0

使用 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 也是如此。

于 2013-07-25T11:11:56.160 回答