2012-04-01 18 views
1

私は、intやシンプルな構造体などのさまざまな値をバイナリファイルにエクスポートしようとしています。ここにいくつかのコードがあります:ostream ::構造体全体が書き込まれませんか?

#include &ltiostream> 
#include &ltfstream> 
#include &ltcstdint> 
using namespace std; 

template&ltclass T> void writeToStream(ostream& o, T& val) 
{ 
    o.write((char*)&val, sizeof(T)); 
    cout << o.tellp() << endl; //always outputs 4 
} 

struct foo { 
    uint16_t a, b; 
}; 

int main() 
{ 
    foo myFoo = {42, 42}; 
    ofstream test("test.txt", ios::binary); 
    writeToStream(test, myFoo); 
    test.close(); 
}

プログラムは4バイトの出力ファイルを生成する必要があります。しかし、私がそれを開くと、2バイトしかありません。 myFoo.amyFoo.bを256以上の値に変更すると(格納に1バイト以上必要)、ファイルは4バイトになります。私はWin7でVisual Studio 11 Developer Previewを使用しています。私は他のシステムやコンパイラで同じことが起こっていないかどうか確認していません。 256以下のaまたはbの値に対して正しく出力するにはどうすればよいですか?

+0

ファイルの長さはどのように決められていますか? –

+0

さて、私はメモ帳++でそれを開いていましたが、それは256未満の値の場合は2文字、それ以外の場合は4文字で表示されました。しかし、私はファイルを右クリックして "プロパティ"をクリックすると4バイトを表示します... – Mark

+3

私はそこにあなたの問題があると思います。バイナリファイルサイズをテキストエディタで表示して決定しようとしています。 –

答えて

2

ファイルは、それが格納されている形式を理解しているプログラムによってのみ読み取られます。メモ帳++は、ファイルが格納されている形式を理解していないので、それを読み込んで分かりやすく表示する能力はありません。メモ帳のような形式のファイルをASCIIテキストなどのファイルに書き込むか、書いた書式を理解するプログラムでファイルを読み込みます。

+0

ファイルブラウザまたはターミナルコマンドを使用してファイルサイズを決定してください... – Potatoswatter

+0

メモ帳++は通常、ヌル文字とそのようなものを表示するため、私は捨てられたと思います。しかし、私は16進エディタでNotepad ++が間違っていることを確認しました。 – Mark

0

コードを次のように整理しました。私は古いコードが2バイトを出力する理由はわかりませんが、新しいコードは4を出力します。

#include <iostream> 
#include <fstream> 
#include <cstdint> 
using std::cout; 
using std::endl; 
using std::uint16_t; 
using std::ostream; 
using std::ofstream; 
using std::ios; 

template <class T> void writeToStream(ostream& o, T& val) 
{ 
    o.write(reinterpret_cast<char *>(&val), sizeof(T)); 
    cout << o.tellp() << endl; //always outputs 4 
} 

struct foo { 
    uint16_t a, b; 
}; 

int main() 
{ 
    foo myFoo = {42, 42}; 
    ofstream test("test.txt", ios::binary); 
    writeToStream(test, myFoo); 
    // Just let the stream "test" pass out of scope. 
    // It closes automatically. 
    //test.close(); 
    return 0; 
} 

(私の標準ライブラリはcstdintを欠い、ので、私はshortではなくuint16_t,を使用しますが、私は、これは重要ことを疑う。)

std::ofstreamタイプはstd::ostreamから派生しています。 writeToStream()関数は、平文であるstd::ostreamが渡された場合、より幸せです。少なくとも少なくともより一般的です。また、情報として:using namespace std;を発行することは、C++ではお勧めできません。

幸運。

+1

あなたのプログラムは彼と同じであると思われます、彼はすでに働いているので、それは動作します。 – Potatoswatter

関連する問題