I am using Winsock, I want to send some values from Simulink to my own program and then I'll use that values in my mathematical equations. My computer is 64-bits, so that a char is 2 bytes and a float is 8 bytes. I want to get 3 elements in my buffer so that I declared my buffer as char buffer[12]. Now I need to merge buffer[0],buffer[1],buffer[2],buffer[3] and buffer[4],buffer[5],buffer[6],buffer[7] and ... so on and want to have a value like 12.23456. How can I do this and cast (or convert) it to float in order to use that values in my mathematical equations?
Here what I tried so far:
#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;
}
This code does not compile because it has errors about strings.
There is some confusion in your question. A char
occupies 1 byte, 64-bit system or not, and a float
occupies 4 bytes. However, you should express the size of a float simply as sizeof(float)
to avoid an unnecessary assumption.
Your Windows PC is a little-endian system and I assume that Simulink is transmitting the values to your program as 32-bit little-endian floats, so there is no endian-conversion to worry about. (But check the Simulink settings in case I am wrong either about the 32-bit or the little-endian).
I also assume the values are being transimitted such that you can count on receiving 3 at time, as you want to (though I don't know why you require them bundled in 3s).
In that case, your receive buffer, now declared as char buf[12];
should be declared as char buf[sizeof(float) * 3];
Then, delete:
char myString[4];
strcpy(myString,buf[0]);
strcat(myString,buf[1]);
strcat(myString,buf[2]);
strcat(myString,buf[3]);
//cast it to float
and replace it with:
float af[3];
for (unsigned i = 0; i < 3; ++i) {
memcpy(af + i,buf + (i * sizeof(float)),sizeof(float));
}
This will copy 3 consecutive floats from buf
into the 3 floats af[0]
, af[1]
, af[2]
. Read about memcpy
here .
That is the sufficient to solve your problem. But I would strongly suggest that you check the return value of recvfrom
and act accordingly. If the call has been successful it will return the number of bytes received as int
; otherwise SOCKET_ERROR
.
You need the return value to be 3 * sizeof(float)
for this code to work. More flexible code would just ensure that it is a multiple of sizeof(float)
and then extract as many floats as you have got. And in any case you need to handle SOCKET_ERROR
.
As to the string-related compilation errors you were seeing, they were due to the same mistake in your call strcpy(myString,buf[0])
and in each your calls strcat(myString,buf[n])
. The signature of strcpy
is:
char * strcpy ( char * destination, const char * source );
and that of strcat
is:
char * strcat ( char * destination, const char * source );
In each case the second argument must be a const char *
and in each case you are passing a char
. That is what the compiler's error messages were telling you:
error C2664: 'strcpy' : cannot convert parameter 2 from 'char' to 'const char *'
error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
Using C++11, you can do it painlessly in this way:
#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() is new since C++11. As is the initialization of s via an initializer list.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.