与VC2012中的fwrite混淆

时间:2014-01-20 08:41:58

标签: c visual-studio visual-studio-2012 fwrite

我需要将一些二进制数据写入文件。格式为uint64_t

  #include <stdio.h>
  #include <assert.h>
  typedef unsigned long long uint64_t;

  int main()
  {
    FILE * file = fopen("data","w");assert(file);
    uint64_t a[]={16000550, 1051320,14456018, 4743184,11840752 ,4225032,\
                      13642264,6059108,563784 ,11823354,3989084 ,15759410,\
                      13413018 ,1582802,1574952 ,1635384,1102996 ,10511428,\
                      10239562 ,9472574,2641952 ,1350256,3432142 ,9920,11573360,\
                      12121180,10255874 ,3198684,7628524,16522766,12908660,\
                      2681374,9482820 ,6354462,15230702 ,16255676,5813862, \
                      8174782,7642752,7362790,6089340 ,803928,2669686 ,4225032,\
                      7603956 ,16551562,15734364 ,14424308,12060282 ,572450,\
                      18432 ,10276902,8134910 ,10749010,14166126 ,1636942,\
                      5295788 ,12342876,2151156 ,12322948};
     for(int i=0;i<sizeof(a)/sizeof(uint64_t);i++)
     {
    fwrite((char*)&a[i],sizeof(uint64_t),1,file);
     }
         fclose(file);
  }

我发现只有当数组的大小很大时,输出才能满足我的期望,所以我在我的例子中给出了60 uint64_t个。

在测试中,我发现它会为0000 fe20 7c00 0000输出8134910。此外,还存在其他一些错误。在海湾合作委员会,它运作良好,在VS2012,它运作不好。

1 个答案:

答案 0 :(得分:2)

根据您在评论中的反馈,VS2012中的不同之处是因为该文件已在“文本”模式下由defualt打开。在此模式下,写入时的每个\n都会扩展为\r\n,这会损坏您的数据。

解决方案是以二进制模式显式打开文件:

FILE * file = fopen("data","wb")

从MSDN上引用可能附加到模式的 t b 字符

  

t

     

以文本(翻译)模式打开。在此模式下,解释CTRL + Z.   作为输入的EOF字符。在打开的文件中   使用“ a + ”进行读/写, fopen 检查结尾处的CTRL + Z   文件并删除它,如果可能的话。这样做是因为使用 fseek   并且 ftell 在以CTRL + Z结尾的文件中移动可能会导致 fseek   在文件末尾附近表现不正确。

     

在文本模式下,将转换回车换行组合   在输入上输入单个换行符,并换行换行符   在输出上运输返回换行组合。当一个Unicode   stream-I / O函数在文本模式(默认),源或文件模式下运行   假定目标流是多字节序列   字符。因此,Unicode流输入函数转换   多字节字符到宽字符(就像通过调用 mbtowc 一样   功能)。出于同样的原因,Unicode流输出功能   将宽字符转换为多字节字符(就像通过调用    wctomb 功能)。

     

b

     

以二进制(未翻译)模式打开;翻译涉及   回车符和换行符被抑制。

     

如果在模式中未指定 t b ,则默认翻译模式为   由全局变量_fmode定义。

_fmode的MSDN文档说:

  

文本模式的默认设置_fmode _O_TEXT   翻译。 _O_BINARY 是二进制模式的设置。