2013-04-16 29 views
0

我正在向C中的二進制文件寫入結構。 char *項目和uint8項目寫入正常,但我似乎遇到寫入uint32項目的問題。寫入/讀取二進制文件的uint問題

我寫的代碼就在這裏。

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

或12月 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'

任何一個在那裏都有任何想法,我哪裏會錯在這裏?

注意mods:不確定我選擇的標籤,調整值得歡迎。

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

感謝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'

再次,任何瞭解每個值的摘錄?

+0

我唯一擔心的是它是否回寫在ok! – John3136

+0

它不會傷心,因此爲什麼我追溯到閱讀二進制。 – TrewTzu

+2

確保你瞭解[endianness](http://en.wikipedia.org/wiki/Endianness)是如何工作的。 –

回答

3

72 92 01 00是十進制103026的正確十六進制/字節表示形式,如果您打算將它寫成little-endian(表示最不重要的字節在前)。如果你把它寫成little-endian並以big-endian(最重要的字節在前)讀取它,那麼這就是你的問題 - 在閱讀和寫作時排序必須一致。

+0

如果即時通訊寫和閱讀在同一個系統上,只有fwrite和fread,它應該使用相同的字節順序嗎? – TrewTzu

+0

@TrewTzu可能不是:http://stackoverflow.com/questions/8556927/why-does-fread-mess-with-my-byte-order – Patashu

+0

這是我的最後一個問題。謝謝! – TrewTzu

4

沒有什麼錯。 72 92 01 00是用於將數字103026表示爲32位小尾數整數的正確字節序列。

5

正如其他人指出的,你的二進制表示看起來是正確的。然而,你應該看看你用來訪問這個文件的模式。當編寫一個二進制文件時,你應該打開模式「wb」並在讀取它時「rb」。

在* nix系統上它並不重要。在Windows上,根據我的經驗,這很重要。不正確的模式很容易導致後續的讀取工作不正確。

+0

即時工作在尼克斯,但我會改變任何方式,謝謝! – TrewTzu

+0

「b」模式只是禁止換行和回車轉換(來自[MSDN](http://msdn.microsoft.com/en-us/library/yeby3zcb(v = vs.71).aspx)) –

+0

@AnishRam :感謝您的鏈接。這確實足以嚴重損壞你的二進制I/O,而且在文本模式下^ Z被視爲EOF。 – FatalError