2013-04-16 55 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