将字符数组解释为多个连接的数据类型
Interpreting Char-Array to Multiple concatenated Datatypes
我通过套接字接收字节流(或 C++ 中的字符)。现在我想解释它们。我知道哪些数据类型隐藏在字节后面。我的消息看起来像这样:
value1 --> char (1 byte)
value2 --> long (8 bytes)
value3 --> short (2 bytes)
...
如何才能高效地实现口译?
//编辑:这不起作用,字节描述的不是字符而是整数。
我考虑过使用 memcpy 和 atoi(目前尚未测试):
char value1 = *charPtr;
charPtr++;
char value2[8]="";
std::memcpy(charPtr,value2,8);
long v2 = atoi(value2);
charPtr+=8;
char value3[2]="";
std::memcpy(charPtr,value3,2);
short v3 = atoi(value3);
charPtr+=2;
我假设您正在尝试将数据作为原始字节流发送,并且您已经确信发送方和接收方使用相同的浮点格式和同样的结局.
但是你的打包数据流显然违反了发送端和接收端的对齐规则,所以我们不能做像value2 = *(long *)data;
这样的事情
那么,尝试使用 parsePackedStruct(data, &value1, &value2, &value3);
合理的实现可以是:
void parsePackedStruct(char *data, char *pValue1, long *pValue2, short *pValue3)
{
memcpy(pValue1, data, sizeof(*pValue1));
data = data + sizeof(*pLalue1);
memcpy(pValue2, data, sizeof(*pValue2));
data = data + sizeof(*pLalue2);
memcpy(pValue3, data, sizeof(*pValue3));
}
这要求您的发送方和接收方对 char/short/long
具有严格相同的大小,这对我来说似乎太严格了,因为 long
的大小因平台而异比其他算术类型更频繁。出于同样的原因,我也会避免使用 bool
并使用 uint8_t
.
所以考虑像 int32_t
.
这样的 C99 整数类型
假设发送方和接收方对于原始数据完全同步 sent/received,您可以这样做:
#pragma pack(push, 1)
struct MyPackedData {
char c;
long l;
short s;
};
#pragma pack(pop)
...
MyPackedData parsedData;
memcpy(&parsedData, charPtr, sizeof(parsedData));
好的,我知道怎么做了。关键字是位移位:
long readAndSkipLong(char*& b)
{
unsigned long ret = (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3]<<32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
b+=8;
return ret;
}
int readAndSkipInt(char*& b)
{
int32_t ret = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
b+=4;
return ret;
}
short readAndSkipShort(char*& b) {
short ret = (b[0] << 8) | (b[1]);
b+=2;
return ret;
}
...
while (readChar(it)!='#') // stop at the terminating char
{
readAndSkipShort(it);
readAndSkipInt(it);
}
...
尽管如此,我对 long 和 int 的转移似乎并不正确。对于预期值
152 --> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10011000
我解读:
-104 --> 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10011000
知道错误在哪里吗?
我通过套接字接收字节流(或 C++ 中的字符)。现在我想解释它们。我知道哪些数据类型隐藏在字节后面。我的消息看起来像这样:
value1 --> char (1 byte)
value2 --> long (8 bytes)
value3 --> short (2 bytes)
...
如何才能高效地实现口译?
//编辑:这不起作用,字节描述的不是字符而是整数。
我考虑过使用 memcpy 和 atoi(目前尚未测试):
char value1 = *charPtr;
charPtr++;
char value2[8]="";
std::memcpy(charPtr,value2,8);
long v2 = atoi(value2);
charPtr+=8;
char value3[2]="";
std::memcpy(charPtr,value3,2);
short v3 = atoi(value3);
charPtr+=2;
我假设您正在尝试将数据作为原始字节流发送,并且您已经确信发送方和接收方使用相同的浮点格式和同样的结局.
但是你的打包数据流显然违反了发送端和接收端的对齐规则,所以我们不能做像value2 = *(long *)data;
那么,尝试使用 parsePackedStruct(data, &value1, &value2, &value3);
合理的实现可以是:
void parsePackedStruct(char *data, char *pValue1, long *pValue2, short *pValue3)
{
memcpy(pValue1, data, sizeof(*pValue1));
data = data + sizeof(*pLalue1);
memcpy(pValue2, data, sizeof(*pValue2));
data = data + sizeof(*pLalue2);
memcpy(pValue3, data, sizeof(*pValue3));
}
这要求您的发送方和接收方对 char/short/long
具有严格相同的大小,这对我来说似乎太严格了,因为 long
的大小因平台而异比其他算术类型更频繁。出于同样的原因,我也会避免使用 bool
并使用 uint8_t
.
所以考虑像 int32_t
.
假设发送方和接收方对于原始数据完全同步 sent/received,您可以这样做:
#pragma pack(push, 1)
struct MyPackedData {
char c;
long l;
short s;
};
#pragma pack(pop)
...
MyPackedData parsedData;
memcpy(&parsedData, charPtr, sizeof(parsedData));
好的,我知道怎么做了。关键字是位移位:
long readAndSkipLong(char*& b)
{
unsigned long ret = (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3]<<32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
b+=8;
return ret;
}
int readAndSkipInt(char*& b)
{
int32_t ret = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
b+=4;
return ret;
}
short readAndSkipShort(char*& b) {
short ret = (b[0] << 8) | (b[1]);
b+=2;
return ret;
}
...
while (readChar(it)!='#') // stop at the terminating char
{
readAndSkipShort(it);
readAndSkipInt(it);
}
...
尽管如此,我对 long 和 int 的转移似乎并不正确。对于预期值
152 --> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10011000
我解读:
-104 --> 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10011000
知道错误在哪里吗?