C ++二进制文件无法正确读取

问题描述

我正在读取在c ++中的高位字节序intel处理器上以高位字节序编写的文件。该文件是用二进制文件编写的通用文件。我尝试使用open()和fopen()两者来读取它,但是它们似乎都弄错了同一件事。该文件是用于训练MNIST数据集中的图像的二进制文件。它包含4个标头,每个标头大小为32位,并以高位字节序存储。我的代码正在运行,只是没有为第二个标头提供正确的值。它适用于其余的标题。我什至在十六进制编辑器中打开了该文件,以查看该值是否可能错误但正确。出于某种奇怪的原因,该程序错误地读取了第二个标头的值: 以下是仅读取标头的代码:

void DataHandler::readInputData(std::string path){
    uint32_t headers[4];
    char bytes[4];
    std::ifstream file;
    //I tried both open() and fopen() as seen below
    file.open(path.c_str(),std::ios::binary | std::ios::in);
    //FILE* f = fopen(path.c_str(),"rb");
    if (file)
    {
        int i = 0;
        while (i < 4)//4 headers
        {
            //if (fread(bytes,sizeof(bytes),1,f))
            //{
            //    headers[i] = format(bytes);
            //    ++i;
            //}
            file.read(bytes,sizeof(bytes));
            headers[i++] = format(bytes);
        }
        printf("Done getting images file header.\n");
        printf("magic: 0x%08x\n",headers[0]);
        printf("nImages: 0x%08x\n",headers[1]);//THIS IS THE ONE THAT IS GETTING READ WRONG
        printf("rows: 0x%08x\n",headers[2]);
        printf("cols: 0x%08x\n",headers[3]);
        exit(1);
        //reading rest of the file code here
    }
    else
    {
        printf("Invalid Input File Path\n");
        exit(1);
    }
}

//converts high endian to little indian (required for Intel Processors)
uint32_t DataHandler::format(const char * bytes) const
{
    return (uint32_t)((bytes[0] << 24) |
        (bytes[1] << 16) |
        (bytes[2] << 8) |
        (bytes[3]));
}

我得到的输出是:

Done getting images file header.
magic: 0x00000803
nImages: 0xffffea60
rows: 0x0000001c
cols: 0x0000001c

nImage的十六进制数应为60,000或(0000ea60)h,但由于某些原因,它会将其读取为ffff...。 这是在十六进制编辑器中打开的文件:

File in hex editor

我们可以看到,第二个32位数字是0000ea60,但它读错了...

解决方法

似乎char已在您的环境中签名,因此数据中的0xEA被符号扩展到0xFFFFFFEA。 这将破坏高位数字。

为防止这种情况,您应该使用unsigned char而不是char。 (对于bytes的元素类型和format()的自变量)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...