26

float将值导出到文件时遇到了一个奇怪的问题。我希望每个浮点数都具有相同的长度(显然),但我的程序有时将其导出为 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)字节,每四个字节代表一个浮点数。但是,我明白了:

 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 

所以floattemp2需要5个字节而不是4个字节,他文件的总长度是23。这怎么可能?!这个数字并没有小到低于正常数字,我想不出任何其他原因会导致大小有所不同。

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

注意: 我已经在这里问了一个非常相似的问题,但是当我意识到问题更普遍时,我决定以更简洁的方式重新发布。 QDataStream 有时使用 32 位,有时使用 40 位浮点数

4

2 回答 2

41

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

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

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

于 2013-04-02T15:47:37.627 回答
12

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

改变这个:

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

对此:

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

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

于 2013-04-02T15:48:48.760 回答