Что может заставить программу Labwindows / CVI C ненавидеть число 2573? - PullRequest
3 голосов
/ 22 октября 2009

Использование Windows

Итак, я читаю из двоичного файла список беззнаковых значений данных int. Файл содержит несколько наборов данных, перечисленных последовательно. Вот функция для чтения одного набора данных из символа *, указывающего на его начало:

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. Что может вызвать это, совершенно непонятно для меня.

Ответы [ 2 ]

11 голосов
/ 22 октября 2009

Вы не указываете, как вы получили байты в памяти (на которые указывает поток), и на какой платформе вы работаете, но я не удивлюсь, если вы найдете их в Windows, и вы использовали C stdio вызов библиотеки fopen(filename "r"); Попробуйте использовать fopen(filename, "rb");. В Windows (и MS-DOS) fopen () переводит окончания строк MS-DOS «\ r \ n» (hex 0x0D 0x0A) в файле в стиль Unix «\ n», если только вы не добавили «b» в файловый режим для обозначения двоичного.

0 голосов
/ 22 октября 2009

Пара несущественных пунктов.

sizeof (* набор данных) не делает то, что вы думаете.

Нет необходимости использовать поиск при каждом чтении

Я не понимаю, как вы вызываете функцию, которая принимает только один параметр, но вы даете ему два (или по крайней мере я не понимаю, почему ваш компилятор не возражает)

...