Okay I am editing my original post. Apologies for not being clear enough earlier. I am relatively new to the developer role, specifically C,C ,Python and Embedded Linux.
There is a python list plist = [2,434]
This data is sent to another program written in C using socket programming.
plist = str(plist)
sock = socket.socket(socket.AF_INET, socket.SOCK_STRREAM)
sock.connect(('localhost',12345))
sock.send(plist.encode('utf-8'))
sock.close()
Now this data is received by the C program as a string. I just made a sample string as follows to give you an idea what I am getting at the C end.
const char* construct= "[2,434]";
Now I am trying to assign the two numbers, 2 and 434, to playerType
and playerID
respectively, which are part of the following structure called PLAYER_HEADER.
typedef enum
{
START,
STOP,
PAUSE,
RECORD
}PLAYER_TYPE;
typedef struct
{
PLAYER_TYPE playerType;
unsigned long playerID;
}PLAYER_HEADER;
So far I've tried this approach, where I am typecasting the string to a struct type.
PLAYER_HEADER* p= (PLAYER_HEADER* ) construct;
player = p->playerType;
cout<<(char)player<<endl;
But this prints only '[' which is the first character of [2,434]
I would like to know why this is happening. Is there a way I can get the rest of the data?
I get that I have typecasted as a character.
My end goal is to assign the two numbers to playerType
and playerID
.
Is there any other way I can do this? Or is there a concept in C I need too understand to solve this problem?
CodePudding user response:
C is a powerful language but part of that power is to let you do things that aren't "correct". The way you are trying to cast a char *
to a PLAYER_HEADER*
just doesn't work as you are expecting it to. You need to parse the string, ignoring parts you don't want and converting the parts you keep to the correct data type.
One way to do this is with std::stringstream
:
PLAYER_HEADER player;
std::istringstream ss(construct);
int temp;
ss.ignore(100, '['); // Skip [
if (ss >> temp) {
player.playerType = (PLAYER_TYPE)temp;
ss.ignore(100, ','); // Skip ,
if (ss >> player.playerID) {
// Success. Do something.
}
}
Another option is regex:
PLAYER_HEADER player;
std::smatch match;
std::regex re(R"(\[(\d ),(\d )\])");
std::string construct_str(construct);
if (std::regex_search(construct_str, match, re)) {
playerType = (PLAYER_TYPE)std::stoi(match[1]);
playerID = std::stoi(match[2]);
// Success. Do something.
}
There are still other ways, but the main point is that you need to learn why your casting doesn't work. With your code:
PLAYER_HEADER* p= (PLAYER_HEADER* ) construct;
player = p->playerType;
cout<<(char)player<<endl;
p
points to the first char in "[2,434]"
which is a [
. Then playerType
most likely has an offset of 0
in the struct so player
also ends up pointing to the [
. Then when you print it as a char
you get [
.