【问题标题】:Issue writing/reading a uint to a binary file将 uint 写入/读取到二进制文件的问题
【发布时间】:2013-04-16 02:00:32
【问题描述】:

我正在将结构写入 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

或在 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'

有人知道我哪里出错了吗?

模组注意事项:不确定我选择的标签,欢迎调整。

--------更新--------

感谢您对 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”之外的所有值

再一次,有什么见解吗?

【问题讨论】:

  • 我唯一担心的是它是否可以正常读取!
  • 它一点也不可悲,因此我回溯阅读二进制文件。
  • 确保您了解endianness 的工作原理。
  • 你为什么认为这些特定的块是一个问题?

标签: c binaryfiles uint


【解决方案1】:

正如其他人所说,您的二进制表示看起来是正确的。但是,您应该查看一下用于访问此文件的模式。写入二进制文件时,您应该以“wb”模式打开,读取时应使用“rb”模式。

在 *nix 系统上它并不重要。在 Windows 上,根据我的经验,这很重要。不正确的模式很容易导致后续读取工作不正常。

【讨论】:

  • 我目前正在使用 nix,但我会改变它,谢谢!
  • “b”模式只是禁止换行和回车翻译(来自MSDN
  • @AnishRam:感谢您的链接。这确实足以严重破坏您的二进制 I/O,而且 ^Z 在文本模式下被视为 EOF。
【解决方案2】:

没有错。 72 92 01 00 是将数字 103026 表示为 32 位小端整数的正确字节序列。

【讨论】:

    【解决方案3】:

    72 92 01 00 是 103026 十进制的正确十六进制/字节表示,如果您打算将其写入 little-endian(这意味着最不重要的字节在前)。如果您将其写入 little-endian 并以 big-endian 读取(最重要的字节在前),那就是您的问题 - 读取和写入的字节序必须相同。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 2021-12-26
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    相关资源
    最近更新 更多