如何通过c ++文件函数以8位整数单位形式读写数据

时间:2014-08-07 19:24:41

标签: c++ casting fstream portability

是否可以以0到255之间的整数形式存储数据而不是8位字符。虽然两者都是一样的,但我们怎么能这样做,例如,使用write()函数? 是否可以直接将任何整数转换为char,反之亦然?有类似

的东西
{
    int a[1]=213; 
    write((char*)a,1);
} 

{
    int a[1]; 
    read((char*)a,1); 
    cout<<a;
}

从文件中的同一位置获取213的工作?它可以在那台计算机上运行但是它是可移植的,换句话说,它是否适合以这种方式进行跨平台项目?如果我使用这个原则为每个游戏关卡创建一个文件格式(它将在当前关卡的文件中存储对象的坐标),它是否可以在其他计算机/系统/平台上运行以便加载相同级别?

3 个答案:

答案 0 :(得分:2)

您显示的代码将写入a[0]对象表示的第一个(最低地址)字节 - 可能是也可能不是值为213的字节。 int的特定对象表示是定义的imeplementation。

使用值213写入一个字节的可移植方式是

unsigned char c = a[0];
write(&c, 1);

答案 1 :(得分:0)

它会起作用,但有一些警告:

  1. 使用reinterpret_cast<char*>(x)代替(char*)x明确表示您正在执行通常不安全的演员表。

  2. sizeof(int)因平台而异,因此您可能希望使用<cstdint>中的固定大小整数类型,例如int32_t

  3. Endianness在平台之间也可能不同,因此在编写文件时,您应该注意平台字节顺序和交换字节顺序为一致的格式。您可以detect endianness at runtime手动交换字节,或use htonl and ntohl在主机和网络(大端)字节顺序之间进行转换。

  4. 另外,作为一个实际问题,我建议您更喜欢基于文本的格式 - 它们不太紧凑,但在出现问题时更容易调试,因为您可以在任何文本编辑器中检查它们。如果您确定加载和解析这些文件太慢,请考虑转换为二进制格式。

答案 2 :(得分:0)

你有正确的想法,但它可以使用一些改进。

{
    int intToWrite = 213;
    unsigned char byteToWrite = 0;

    if ( intToWrite > 255 || intToWrite < 0 )
    {
        doError();
        return();
    }

    // since your range is 0-255, you really want the low order byte of the int.
    // Just reading the 1st byte may or may not work for your architecture. I
    // prefer to let the compiler handle the conversion via casting.
    byteToWrite = (unsigned char) intToWrite;

    write( &byteToWrite, sizeof(byteToWrite) );
    // you can hard code the size, but I try to be in the habit of using sizeof
    // since it is better when dealing with multibyte types
}

{
    int a = 0;
    unsigned char toRead = 0;

    // just like the write, the byte ordering of the int will depend on your
    // architecture. You could write code to explicitly handle this, but it's
    // easier to let the compiler figure it out via implicit conversions
    read( &toRead, sizeof(toRead) );

    a = toRead;
    cout<<a;
}

如果您需要最小化空间或者无法承受额外的字符,那么它绝对可以读取/写入整数中的特定位置。但是,它可能需要在新标题中链接(例如使用htons / ntons)或烦人(使用平台#defines)。