2013-04-02 103 views
25

当将float值导出到文件时,我遇到了一个奇怪的问题。我希望每个浮点数都是相同的长度(很明显),但是我的程序有时会输出一个32位数字,有时也会输出一个40位数字。 一个程序,仍然显示这种行为的最小工作示例是:浮点数的长度在32位和40位之间变化

#include <stdio.h> 

const char* fileName = "C:/Users/Path/To/TestFile.txt"; 
float array [5]; 

int main(int argc, char* argv []) 
{ 
    float temp1 = 1.63006e-33f; 
    float temp2 = 1.55949e-32f; 

    array[0] = temp1; 
    array[1] = temp2; 
    array[2] = temp1; 
    array[3] = temp2; 
    array[4] = temp2; 

    FILE* outputFile; 
    if (!fopen_s(&outputFile, fileName, "w")) 
    { 
     fwrite(array, 5 * sizeof(float), 1, outputFile); 
     fclose(outputFile); 
    } 

    return true; 
} 

我期望输出文件,以包含正好20(5次4)个字节,其中每个4的表示一个浮子。不过,我得到这个:

8b 6b 07 09  // this is indeed 1.63006e-33f 
5b f2 a1 0d 0a // I don't know what this is but it's a byte too long 
8b 6b 07 09  
5b f2 a1 0d 0a 
5b f2 a1 0d 0a 

所以浮动temp2需要5个字节而不是四个,而他的文件的总长度为23。这怎么可能?这个数字并不是很小,它们是低于正常的数字,我想不出任何其他的原因为什么会有差异。

我在64位Windows 7系统上使用MSVC 2010编译器。

注:我已经问了一个非常类似的问题在这里,但我也意识到问题比较一般,我决定重新发布它更简洁的方式。 QDataStream uses sometimes 32 bit and sometimes 40 bit floats

+2

基本上,从来没有用'b'打开任何带'fopen'的文件。 – zneak

+1

只是很高兴你的测试值之一不是'0.5392157'! –

+1

[Binary and Text Mode](http://stackoverflow.com/questions/229924/difference-between-files-writen-in-binary-and-text-mode#) –

回答

41

问题是,在Windows上,你必须区分文本和二进制文件。将文件以文本形式打开,这意味着在写入每个0a(换行符)之前插入0d(回车)。像这样打开文件:

if (!fopen_s(&outputFile, fileName, "wb")) 

其余的和以前一样,它应该工作。

+1

获得这样一个微妙的错误的荣誉。 –

+1

这真是太神奇了,这封信解决了一切(即两天将我的头撞在墙上)。 – Yellow

+1

别担心,有时我们都会有这种感觉。 –

12

你不是在写文字;您正在编写二进制数据...但是,您的文件是开放的书写文本"w")而不是编写二进制"wb")。因此,fwrite()正在翻译'\n'"\r\n"

更改此:

if (!fopen_s(&outputFile, fileName, "w")) 

要这样:

if (!fopen_s(&outputFile, fileName, "wb")) 

"wb",在b代表二进制模式。

相关问题