C++ 二进制文件读取问题

3

我正在编写一个函数,用于读取包含一些转储数据(一系列1字节值)的文件。由于转储值每个都是1字节,所以我将它们作为字符读取。我以二进制模式打开文件,将数据读取为字符,并进行强制类型转换为int(以便获取ASCII代码)。但是读取的数据不正确(在十六进制编辑器中进行比较)。以下是我的代码:

int** read_data(char* filename, int** data, int& height, int& width)
{
    data=new int*[height];
    int row,col;
    ifstream infile;
    infile.open(filename,ios::binary|ios::in);
    if(!infile.good())
    {
        return 0;
    }
    char* ch= new char[width];
    for(row=0; row<height; row++)
    {
        data[row]=new int[width];
        infile.read(ch,width);
        for(col=0; col<width; col++)
        {
            data[row][col]=int(ch[col]);
            cout<<data[row][col]<<" ";
        }
        cout<<endl;
    }
    infile.close();
    return data;
}

这段代码可能有什么问题呢?我使用的是Windows操作系统,Visual Studio 2005进行开发,传递的确切文件名为:

"D:\\files\\output.dat"
编辑: 如果我不使用无符号字符,前8个值,它们都是245, 会被读取成-11。

2
尝试读取无符号字符并转换为无符号整数。 - Kerrek SB
数据应该在这个函数之外分配。 - longbkit
@longbkit 这是C++。数据不应该手动分配。 - Konrad Rudolph
@longbkit 在这个函数之外,我负责处理“数据”。在这个函数中,值被复制到“数据”数组中。所以,关于数组没有问题,我可以向您保证。 - c0da
你能给我们更多的细节吗?你遇到了什么样的错误? - eugene_che
显示剩余4条评论
3个回答

3

我认为,您可能需要使用无符号字符和无符号整数才能获得正确的结果。在您的代码中,读取的字节被解释为有符号值。我假设这不是您的意图。


但是一个字节就是一个字节。确切的8个字节被复制到8字节数组中。当转储值也是整数时,访问数组的单个元素不是问题。 - c0da
如果转储的值小于127或者原始值也是有符号的,那么你是正确的。 - Kocki
转储的值接近245...我想你们都是对的...我需要使用无符号字符...但是当我这样做时,我又得到了另一个编译错误...infile.read()期望一个char,而不是一个unsigned char - c0da
@cOda:问题在于,如果你的字节是255,你的字符将会是255或-1,这取决于你的平台。但如果它是-1,它将被提升为整数-1。 - Kerrek SB
@cOda:是的,你必须在读取时进行强制类型转换,或者保留字符并稍后进行转换:unsigned int value = (unsigned char)(c); - Kerrek SB

1

你的错误似乎在于使用了char*来代替ch。当你尝试输出它时,所有的字符都会被打印出来,直到第一个零值。


那是我用于在屏幕上打印值的一些调试信息。我编辑了问题。现在请检查。 - c0da
这行代码为行执行单独的数据分配:data[row]=new int[width]; - c0da

0
一个普通的char可以是有符号的或无符号的,这取决于编译器。为了获得一致(和正确)的结果,在分配给int之前,您可以将该值转换为unsigned char
data[row][col]=static_cast<unsigned char>(ch[col]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接