整型转换为字节和反向转换
Int to bytes and backwards
我以二进制格式保存游戏地图到文件中。文件的一般结构为:
- <
- (4字节)宽度/gh><
- (4字节)高度/gh>
- 宽度*高度:
- (1字节)瓷砖
- 宽度*高度:
- <
- (4字节)数据/gh>
为了减小文件的大小,我决定将所有内容保存为字符,因为我知道我想要读取的数字的确切大小。我做了两个函数,getByte和makeInt:
unsigned char getByte(int src, short int c) //get byte number c from src
{
return ((char*)(&src))[c];
}
int makeInt(char src[4]) //build int from src
{
int r=0;
for (int i=3; i>=0; i--)
r+=(r<<8)+((unsigned char*)(src))[i];
return r;
}
下面是我保存和加载地图的方法:
void Map::save(const char *fname)
{
ofstream f;
f.open(fname,fstream::out | fstream::binary);
for (int i=3; i>=0; i--)
f.put(getByte(W,i));
for (int i=3; i>=0; i--)
f.put(getByte(H,i));
for (int i=0; i<W; i++)
for (int j=0; j<H; j++)
f.put(tiles[i][j]);
for (int i=0; i<W; i++)
for (int j=0; j<H; j++)
for (int k=3; k>=0; k--)
f.put(getByte(data[i][j],k));
f.close();
}
void Map::load(const char *fname)
{
ifstream f;
f.open(fname,fstream::in | fstream::binary);
char bytes[4];
for (int i=3; i>=0; i--)
f.get(bytes[i]);
W=makeInt(bytes);
for (int i=3; i>=0; i--)
f.get(bytes[i]);
H=makeInt(bytes);
for (int i=0; i<W; i++)
for (int j=0; j<H; j++)
f.get(tiles[i][j]);
for (int i=0; i<W; i++)
for (int j=0; j<H; j++)
{
for (int k=3; k>=0; k--)
f.get(bytes[k]);
data[i][j]=makeInt(bytes);
}
f.close();
}
tile (char)保存和加载良好,一切正常。但是整型不是。由于奇怪的bug,当我保存256时,我加载257。我读到的不是512,而是514。我不想把它弄脏(r-=r/256)…我也有一些符号问题,这可能就是为什么会发生这些。在添加一些无符号强制转换之前,127之后是-127、-126、-125,等等。下面是map类:
class Map
{
public:
int W;
int H;
char tiles[MW][MH]; //MW and MH are macros, now they are 64.
int data[MW][MH];
void save(const char *fname);
void load(const char *fname);
/* moar code */
};
我通过使用以下模式生成map来测试它:
for (int i=0; i<64; i++)
for (int j=0; j<64; j++)
map.data[i][j]=(i*64+j);
r+=(r<<8)+((unsigned char*)(src))[i];
应为r=(r<<8)+((unsigned char*)(src))[i];
现在,我一般关心的是,也许你不应该过于担心在这里或那里节省一个字节。如果您真的想节省空间,请使用一些适当的压缩技术——霍夫曼编码、字节对或类似的技术。
你确定你节省了任何空间比使用f.r write()和f.r read() -我很确定你的代码会更简单-除非你打算将文件存储在一台机器上,将它们传送到另一台具有不同字节顺序的机器上,然后在那里加载它们的代码,这是大量额外的工作,一次存储一个字节。虽然我相信这是一个很好的学习练习。至少编写一个一次存储一个整型的函数可能会对清理代码有很大帮助。
这是不正确的(function makeInt(char[4])):
r+=(r<<8)+((unsigned char*)(src))[i];
你想要r = r<<8 + ...
。实际上,您不止一次地累积了该值。
相关文章:
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 将字节数组转换为带有字节序问题的指针
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 如何在连接器 C++ 中将原始字节转换为字符串
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- 将字节数组转换为多维数组
- C++如何将字符数组转换为字节向量(向量<byte>)
- 如何在C++中将字节向量(std::vector<uint8_t>)转换为不同的uint32_t,uint16_t和uint8_t变量
- 将字符串转换为无符号字符数组/字节数组
- 将(N 个字节)无符号字符指针转换为浮点数和双 C++
- 将以 null 结尾的字节字符串转换为原始字符串文本
- 正在转换结构数据的字节序
- 如何将 CString 转换为字节 [] 数组?
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 使用 ESP8266/8285 将字符串从 Web 服务器转换为字节数组
- 编译时将字符*转换为字节
- 将字节数组转换为对象C++ |C++中的 C# 位转换器
- C++转换字节
- 将整型转换字节中的字节更改为整数
- c++从字符串化字节转换字节数组