将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
所以float temp2
需要5个字节而不是4个字节,而他的文件总长度是23.这怎么可能?!这个数字不是很小,以至于它们是次正规数,而且我想不出为什么会出现尺寸差异的任何其他原因。
我在64位Windows 7系统上使用MSVC 2010编译器。
注意: 我已经在这里问了一个非常相似的问题,但当我意识到这个问题比较笼统时,我决定以更简洁的方式重新发布它。 QDataStream uses sometimes 32 bit and sometimes 40 bit floats
答案 0 :(得分:41)
问题是在Windows上,您必须区分文本和二进制文件。您将文件作为文本打开,这意味着在每写0d
(换行)之前插入0a
(回车)。像这样打开文件:
if (!fopen_s(&outputFile, fileName, "wb"))
其余的和以前一样,它应该有效。
答案 1 :(得分:12)
你不是在写文字;您正在编写二进制数据...但是,您的文件是打开编写文本("w"
)而不是编写二进制文件("wb"
) 。因此,fwrite()
正在将'\n'
翻译为"\r\n"
。
改变这个:
if (!fopen_s(&outputFile, fileName, "w"))
对此:
if (!fopen_s(&outputFile, fileName, "wb"))
在"wb"
中,b
代表二进制模式。