26

float値をファイルにエクスポートするときに奇妙な問題が発生しました。私はすべての 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) バイトが含まれ、それぞれ 4 バイトが float を表すと予想されます。しかし、私はこれを取得します:

 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は 4 バイトではなく 5 バイトになり、ファイルの全長は 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 に答える