Вопрос

I am writing a struct to a binary file in C. The char* items and the uint8 items are writing fine, but i seem to be having an issue writing the uint32 item.

my writing code is here.

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++;
    }   
}

my binary file looks like this for record one (in hex) (With '|' used to show field ending pointed): 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

or in dec 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

the issue being in the "72 92 01 00" or "114 146 001 000" block. the number it is meant to contain is '103026'

Any one out there have any idea where i'm going wrong here?

note to mods: unsure about my choice of tags, adjustments welcome.

--------UPDATE--------

Thanks for the input on the bin file. Ok seeing as it is writing correctly, i must be reading wrong.

its a excerpt of my reading

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;       

}

It looks right to me and it works for every value except 'Id'

once again, any insight?

Это было полезно?

Решение 3

72 92 01 00 is the correct hexadecimal/byte representation of 103026 decimal, if you are intending to write it little-endian (which means, least important byte first). If you write it little-endian and read it in big-endian (most important byte first), that is your problem - endianness has to be the same on reading and writing.

Другие советы

As the others noted, your binary representation looks correct. You should take a look, however, at the modes you are using to access this file. When writing a binary file you should be opening with mode "wb" and when reading it "rb".

On *nix systems it doesn't tend to matter. On Windows, from my experience, it matters quite a bit. The incorrect mode could easily cause the subsequent read to work incorrectly.

There's nothing wrong. 72 92 01 00 is the correct sequence of bytes for representing the number 103026 as a 32-bit little-endian integer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top