3

使用视窗

所以我正在从二进制文件中读取无符号整数数据值的列表。该文件包含按顺序列出的许多数据集。这是从指向其开头的 char* 读取单个数据集的函数:

function read_dataset(char* stream, t_dataset *dataset){

    //...some init, including setting dataset->size;

    for(i=0;i<dataset->size;i++){
        dataset->samples[i] = *((unsigned int *) stream);
        stream += sizeof(unsigned int);
    }
    //...
}

其中 read_dataset 在这样的上下文中:

//...
char buff[10000];
t_dataset* dataset = malloc( sizeof( *dataset) );
unsigned long offset = 0;

for(i=0;i<number_of_datasets; i++){

    fseek(fd_in, offset, SEEK_SET);

    if( (n = fread(buff, sizeof(char), sizeof(*dataset), fd_in)) != sizeof(*dataset) ){
        break;
    }

    read_dataset(buff, *dataset);

    // Do something with dataset here.  It's screwed up before this, I checked.


    offset += profileSize;
}
//...

一切都顺利进行,直到我的循环读取数字 2573。突然之间,它开始吐出随机和巨大的数字。

例如,应该是什么

...
1831
2229
2406
2637
2609
2573
2523
2247
...

变成

...
1831
2229
2406
2637
2609
0xDB00000A
0xC7000009
0xB2000008
...

如果您认为这些十六进制数字看起来很可疑,那您是对的。原来改变的值的十六进制值真的很熟悉:

2573 -> 0xA0D
2523 -> 0x9DB
2247 -> 0x8C7

所以显然这个数字 2573 导致我的流指针获得一个字节。这一直存在,直到下一个数据集被加载和解析,上帝禁止它包含数字 2573。我检查了许多发生这种情况的位置,我检查的每个位置都从 2573 开始。

我承认我在 C 的世界里没有那么有才华。可能导致这种情况的原因对我来说是完全不透明的。

4

2 回答 2

11

您没有指定如何获取内存中的字节(由流指向),也没有指定您在哪个平台上运行,但是在 Windows 上找到您的我不会感到惊讶,并且您使用了 C stdio 库调用fopen(filename "r");Try使用fopen(filename, "rb");. 在 Windows(和 MS-DOS)上,fopen() 将文件中的 MS-DOS 行尾“\r\n”(十六进制 0x0D 0x0A)转换为 Unix 样式“\n”,除非您将“b”附加到文件模式表示二进制。

于 2009-10-21T22:12:07.557 回答
0

几个无关紧要的点。

sizeof(*dataset) 没有做你认为它做的事情。

无需在每次读取时都使用 seek

我不明白你是如何调用一个只接受一个参数但你给它两个参数的函数(或者至少我不明白为什么你的编译器不反对)

于 2009-10-21T22:09:06.690 回答