我正在以二进制格式将游戏 map 保存到文件中。文件的一般结构是:
- (4字节)宽度
- (4byte) 高度
- 宽度 * 高度:
- (1 字节)瓦片
- 宽度 * 高度:
- (4字节)数据
为了减小文件的大小,我决定将所有内容保存在字符中,因为我知道我想要读取的数字的确切大小。我制作了 2 个函数,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;
}
这是我保存和加载 map 的方式:
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();
}
Tiles (char) 保存和加载良好,一切正常。但是 int 不是。由于奇怪的错误,当我保存 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.write() 和 f.read() 节省了空间吗——我很确定你的代码会简单得多——除非你打算将文件存储在一台机器上,否则它们跨越到另一个具有不同字节顺序的,然后将它们加载到那里的代码中,一次存储一个字节需要很多额外的工作。尽管我确信这是一个很好的学习练习。至少编写一个函数来一次存储一个 int 可能会对清理代码有很大帮助。
关于c++ - 整数到字节和向后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14014820/