2016-03-05 76 views
0

我正在写一个函数,该函数应该在二进制文件中保存3个结构(其中2个是结构数组)。这里是我的功能:将多个结构保存为二进制文件(C)

void saveFile(Struct1 *s1, Struct2 *s2, Struct3 s3) { 
    FILE *fp = NULL; 
    fp = fopen("save.bin", "w+b"); 

    if (fp == NULL) { 
     printf("Save failed.\n"); 
    } 

    fwrite(s1, sizeof(Struct1), struct3.nElements, fp); 
    fwrite(s2, sizeof(Struct2), NELEMENTS, fp); 
    fwrite(&s3, sizeof(Struct3), 1, fp); 

    printf("Save done.\n"); 
} 

s1struct3.nElementss2NELEMENTS(这是一个常数)和s3只是一个结构,而不是一个数组。当我尝试使用HexEditor打开save.bin时,它给出了与我期望的结果截然不同的结果,我想知道是否正确使用了fwrite函数,特别是对于结构数组。

+1

你使用十六进制编辑器得到了哪个结果,你期望得到哪个结果,以及你写入了什么文件。如果你想得到答案,你必须与我们分享这些信息。阅读[MCVE](http://stackoverflow.com/help/mcve)。 –

+0

@MichaelWalz当我使用HexEditor时,我看到了随机字符,一些正确的'struct2'字段以及一些像Visual Studio程序的路径。显然,我期待看到结构的正确价值。 – THZ

+1

显示如何调用'saveFile'。问题可能在那里。并显示'struct1','struct2'和'struct3'的声明。 –

回答

1

有小的问题跟你的功能可能会引发问题:

  • 您定义的函数,通过数值取s3。为什么不把指针传递给第三个struct?调用代码之前saveFile函数是否正确声明?你确定调用代码的价值通过struct

  • 忘记关闭流。手柄会丢失,并且内容不会刷新到磁盘,直到程序退出。

  • 您在"w+b"模式下打开文件:使用read进行写入。使用二进制模式是正确的,但不必为了读取而添加+。只需使用"wb"

  • 如果fopen失败,则输出诊断消息,但不会从该函数返回。尝试写入NULL流指针时,您将调用未定义的行为。

关于你的问题,文件的转储与你期望的不一致......给我们更多的信息,比如不同结构和十六进制转储的定义。这里有一些想法:

  • 结构中的某些字段可能需要特定的对齐,并因此通过填充字节与前一字段分离。这些填充字节的值不一定是0:如果结构处于自动存储或分配给malloc,则它们的初始状态未定义,并且可能会改变为存储其他字段的副作用。
  • 整数可以具有不同的大小,并且可以按文件中的小端或大端顺序存储,具体取决于程序编译的特定体系结构。由于这个原因,程序存储的值只能在相同的体系结构和操作系统上运行,并使用合适的但相当类似的代码读回。
  • 如果您的结构包含指针,您无法从存储在输出文件中的值中真正理解。
+0

“忘记关闭流,句柄丢失,内容不会刷新到磁盘,直到程序退出。”是最好的嫌疑犯。 AFAIK,如果缺少close/flush,数据甚至不需要写入。 – chux

+0

@chux:C11 7.22.4.4:'exit'函数:*接下来,所有打开的未经写入的缓冲数据流将被刷新,所有打开的流将关闭,并删除由tmpfile函数创建的所有文件* – chqrlie

+1

True,但代码不会公布如何结束。考虑'中止_Exit'。 “打开的流被关闭,或临时文件被移除是实现定义的”OP的反射来发布完整的MCVE结构,数据读取和观察到的数据都会在回答这篇文章时造成不必要的挑战。 – chux