Проблема с записью/чтением uint в бинарный файл

Я пишу структуру в двоичный файл на C. Элементы char* и элементы uint8 записываются нормально, но у меня, похоже, проблема с записью элемента uint32.

мой код записи здесь.

void writeOut(record *data){

FILE *fp = fopen("output.bin","w");

int i =0;

    while(data[i].Name != NULL){
        fwrite(data[i].Name, NAME_LEN ,1,fp);   
        fwrite(&data[i].Value1, sizeof(uint8_t) ,1,fp);
        fwrite(&data[i].Value2, sizeof(uint8_t) ,1,fp);
        fwrite(&data[i].Id, sizeof(uint32_t) ,1,fp);
        fwrite(data[i].Text, TEXT_LEN ,1,fp);   
        i++;
    }   
}

мой двоичный файл выглядит так для первой записи (в шестнадцатеричном формате) (с '|', используемым для отображения конца поля): 52 6F 64 27 72 6F 64 00 00 00 00 00 00 00 00 00 00 | 01 | 04 | 72 92 01 00 | 50 72 6F 6A 65 63 74 20 50 65 61 63 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

или в декабре 082 111 100 039 114 111 100 000 000 000 000 000 000 000 000 000 000 | 001 | 004 | 114 146 001 000 | 080 114 111 106 101 099 116 032 080 101 097 099 101 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000

проблема находится в блоке «72 92 01 00» или «114 146 001 000». число, которое он должен содержать, — «103026».

У кого-нибудь есть идеи, где я ошибаюсь?

Примечание для модов: не уверен в своем выборе тегов, корректировки приветствуются.

--------ОБНОВИТЬ--------

Спасибо за вклад в файл bin. Хорошо, если он пишет правильно, я, должно быть, неправильно читаю.

это отрывок из моего чтения

int populateRecordSet(unsigned int pageSize, FILE *recordFile, record** record_set){
// read in data
unsigned char data[RECORD_LEN * pageSize];
int numOfRecords = fread(data, RECORD_LEN, pageSize, recordFile);

// convert to records

int r_pos; //note r_pos is used to show the starting point of a record in the context of the binary file 
int i;
uint32_t test;


for(i=0; i < numOfRecords; i++) {
    r_pos = i * RECORD_LEN;
    memcpy(record_set[i]->Name, data + r_pos, NAME_LEN);
    //ADD NULL AT END JUST IN CASE
    record_set[i]->Name[NAME_LEN] = '\0';

    record_set[i]->Species = *(data + r_pos + (NAME_LEN));

    record_set[i]->Class = *(data + r_pos + (NAME_LEN+SPECIES_LEN));

    //record_set[i]->Id = *(data + r_pos + (NAME_LEN+SPECIES_LEN+CLASS_LEN));
    test = *(data + r_pos + (NAME_LEN+SPECIES_LEN+CLASS_LEN));

    printf("%s::%"PRIu32, record_set[i]->Name,test);
    getchar();

    memcpy(record_set[i]->Guild, data + r_pos + (NAME_LEN+SPECIES_LEN+CLASS_LEN+ID_LEN), GUILD_LEN);
    record_set[i]->Guild[GUILD_LEN] = '\0';
}
getchar();

return i;       

}

Мне это кажется правильным, и оно работает для всех значений, кроме «Id».

еще раз, есть понимание?


person TrewTzu    schedule 16.04.2013    source источник
comment
Единственное, о чем я бы беспокоился, это если он читает обратно в порядке!   -  person John3136    schedule 16.04.2013
comment
К сожалению, это совсем не так, поэтому я вернулся к чтению двоичного файла.   -  person TrewTzu    schedule 16.04.2013
comment
Убедитесь, что вы понимаете, как работает порядок байтов.   -  person Adam Rosenfield    schedule 16.04.2013
comment
Как вы думаете, почему именно эти блоки являются проблемой?   -  person Code-Apprentice    schedule 16.04.2013


Ответы (3)


72 92 01 00 является правильным шестнадцатеричным/байтовым представлением десятичного числа 103026, если вы собираетесь писать его с прямым порядком байтов (что означает, что наименее важный байт будет первым). Если вы пишете с прямым порядком байтов и читаете с прямым порядком байтов (сначала самый важный байт), это ваша проблема - порядок следования байтов должен быть одинаковым при чтении и записи.

person Patashu    schedule 16.04.2013
comment
если я пишу и читаю в одной и той же системе, используя только fwrite и fread, он должен использовать один и тот же порядок байтов, верно? - person TrewTzu; 16.04.2013
comment
@TrewTzu Потенциально нет: stackoverflow.com/questions/8556927/ - person Patashu; 16.04.2013

Как отмечали другие, ваше двоичное представление выглядит правильно. Однако вам следует взглянуть на режимы, которые вы используете для доступа к этому файлу. При записи бинарного файла вы должны открывать его в режиме "wb", а при чтении - "rb".

В системах *nix это не имеет значения. В Windows, по моему опыту, это имеет большое значение. Неправильный режим может легко привести к неправильной работе последующего чтения.

person FatalError    schedule 16.04.2013
comment
Сейчас я работаю над nix, но я все равно его изменю, спасибо! - person TrewTzu; 16.04.2013
comment
Режим b просто подавляет переводы перевода строки и возврата каретки (из MSDN) - person Anish Ramaswamy; 16.04.2013
comment
@AnishRam: Спасибо за ссылку. Этого действительно достаточно, чтобы серьезно испортить ваш двоичный ввод-вывод, но также и того факта, что ^Z обрабатывается как EOF в текстовом режиме. - person FatalError; 16.04.2013

Нет ничего плохого. 72 92 01 00 — правильная последовательность байтов для представления числа 103026 в виде 32-битного целого числа с обратным порядком байтов.

person jwodder    schedule 16.04.2013