想要将字符数组的部分转换/类型转换为值
Want to translate/typecast parts of a char array into values
我正在使用网络,在将大量数据的数据包转换为我想要的值时遇到了一点障碍。
基本上,我已经做了一个我希望我的包看起来有点的模型包。本质上是一个Char(8位值),指示消息是什么,由switch语句检测,然后根据8位值之后的数据填充值。我希望我的包里有各种各样的信息,这些信息可能是不顺序的。
例如,我可能以结尾的心跳结束,或者是聊天消息中的一串文本,等等。
我只是想对我的程序说,从char数组中的某个点获取数据,并将它们类型转换(如果这是术语的话?)成我想要的样子。有什么好的简单方法可以做到这一点?
char bufferIncoming[15];
ZeroMemory(bufferIncoming,15);
//Making a mock packet
bufferIncoming[0] = 0x01; //Heartbeat value
bufferIncoming[1] = 0x01; //Heartbeat again just cause I can
bufferIncoming[2] = 0x10; //This should = 16 if its just an 8bit number,
bufferIncoming[3] = 0x00; // This
bufferIncoming[4] = 0x00; // and this
bufferIncoming[5] = 0x00; // and this
bufferIncoming[6] = 0x09; // and this should equal "9" of its is a 32bit number (int)
bufferIncoming[7] = 0x00;
bufferIncoming[8] = 0x00;
bufferIncoming[9] = 0x01;
bufferIncoming[10] = 0x00; //These 4 should be 256 I think when combines into an unsigned int
//End of mockup packet
int bufferSize = 15; //Just an arbitrary value for now
int i = 0;
while (i < bufferSize)
{
switch (bufferIncoming[i])
{
case 0x01: //Heart Beat
{
cout << "Heartbeat ";
}
break;
case 0x10: //Player Data
{
//We've detected the byte that indicates the following 8 bytes will be player data. In this case a X and Y position
playerPosition.X = ??????????; //How do I combine the 4 hex values for this?
playerPosition.Y = ??????????;
}
break;
default:
{
cout << ".";
}
break;
}
i++;
}
cout << " End of Packetn";
根据Clairvoire的想法,我添加了以下内容:
playerPosition.X = long(bufferIncoming[3]) << 24 | long(bufferIncoming[4]) << 16 | long(bufferIncoming[5]) << 8 | long(bufferIncoming[6]);
注意我改变了周围的移位值
另一个重要的变化是
unsigned char bufferIncoming[15]
如果我不这样做,我得到的是与每个元素的组合混合在一起的负值。我不知道编译器在做什么,但是它真的很烦人。
你可以想象这不是我喜欢的解决方案,但我要试一试。"Chad"有一个很好的例子,说明我可以如何构建它,工作中的一个程序员同事也推荐了他的实现。但是…
我有一种感觉,一定有一种更快更干净的方法来做我想做的事。我试过……
playerPosition.X = *(bufferIncoming + 4) //Only giving me the value of the one hex value, not the combined >_<
playerPosition.X = reinterpret_cast<unsigned long>(&bufferIncoming); //Some random number that I dont know what it was
. .还有一些我删掉的东西,它们也不管用。我期望做的是指向字符缓冲区的某个地方,说"嘿,playerPosition,开始从这个位置读取,并根据字节数据填写你的值"。
例如…
playerPosition = (playerPosition)bufferIncoming[5]; //Reads from this spot and fills in the 8 bytes worth of data
//or
playerPosition.Y = (playerPosition)bufferIncoming[9]; //Reads in the 4 bytes of values
…为什么它不像那样工作,或者类似的东西?
可能有一个漂亮的版本,但我个人会使用左移和or组合四个字符变量,像这样:
playerPosition.X = long(buffer[0]) | long(buffer[1])<<8 | long(buffer[2])<<16 | long(buffer[3])<<24;
序不应该是一个问题,因为按位逻辑总是执行相同的顺序,最低的顺序在右边(就像小数的个位在右边)
编辑:Endianness可能会成为一个因素,这取决于发送机器在通过网络发送整数之前如何初始分割整数。如果它不以与使用移位重新组合整数相同的方式分解整数,那么您可能会得到一个第一个字节是最后一个字节,最后一个字节是第一个字节的值。像这样的小歧义促使大多数人使用网络库,啊哈。
按位分割整数的例子如下
buffer[0] = integer&0xFF;
buffer[1] = (integer>>8)&0xFF;
buffer[2] = (integer>>16)&0xFF;
buffer[3] = (integer>>24)&0xFF;
在典型的消息传递协议中,最直接的方法是拥有一组可以轻松转换的消息,使用继承(或组合)以及字节对齐结构(在这种情况下对于从原始数据指针进行转换很重要)可以使这相对容易:
struct Header
{
unsigned char message_type_;
unsigned long message_length_;
};
struct HeartBeat : public Header
{
// no data, just a heartbeat
};
struct PlayerData : public Header
{
unsigned long position_x_;
unsigned long position_y_;
};
unsigned char* raw_message; // filled elsewhere
// reinterpret_cast is usually best avoided, however in this particular
// case we are casting two completely unrelated types and is therefore
// necessary
Header* h = reinterpret_cast<Header*>(raw_message);
switch(h)
{
case HeartBeat_MessageType:
break;
case PlayerData_MessageType:
{
PlayerData* data = reinterpret_cast<PlayerData*>(h);
}
break;
}
我在Skype上与我认识的一个程序员交谈,他向我展示了我正在寻找的解决方案。
playerPosition.X = *(int*)(bufferIncoming+3);
我不记得怎么让它工作,或者它叫什么。但现在看来一切都好了。
谢谢大家的帮助:)
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 字符类型转换不兼容
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- C++:用户定义的显式类型转换函数错误
- 无法转换类型 C++
- 将类指针类型转换为键时出错
- 通过引用传递参数时C++类型转换
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- C++无效的函数类型转换
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何将Windows产品类型转换为名称?
- 通过构造函数方法输出的类到类类型转换是 5500 为什么不是 5555
- 事件系统:使用类型转换或联合进行继承
- 想要将字符数组的部分转换/类型转换为值