2017-04-23 8 views
0

私が読んでいる本では、バイナリについて話を始めました。バイナリファイルに出力する方法は、テキストファイルに出力する方法と同様です。だから私はもっと読むことを始め、試してみたいです。しかし、私は簡単な問題のように思えるものに遭遇しましたが、バイナリファイルに関しては私が理解していないことを考慮して正しく理解していません。C++のバイナリファイルへの出力に問題があります

したがって、構造体と関数を作成しました。以下のように。

file.write(address, size) 
:本の中で、それは私がバイナリに出力することに次のようなものを書くべきであると述べ、今

void BinaryCreation(celebrities actors) 
{ 

     fstream file; 
     file.open("binaryfile.txt", ios::binary | ios::out); 

struct celebrities 
{ 
    char name[15]; 
    char lastName[15]; 
}; 
void BinaryCreation(celebrities); 
int main() 
{ 
    celebrities actors = { "Denzel", "Washington" }; 

    BinaryCreation(actors); 

    system("pause"); 

} 

今、私は、バイナリファイルを作成します

どのように私は構造を持っている場合、どのように正確に私はそれを行うのですか?私は以下を試しました:

file.write(&actors.name, sizeof(actors.name)); 
file.write(&name, sizeof(name)); 

また、再解釈キャストを試みました。 は、私はまた、エラーなしの意味で働いていた以下の

file.write(actors.name, sizeof(actors.name)); 

をしましたが、それは、出力はテキスト形式(ASCII)でファイルになります。

私はこれがとても簡単で、何かを見落としていると確信していますが、現時点ではわかりません。

+1

出力タイプをバイナリに変更しても、魔法のようにテキストが変更されることはありません。それはまだテキストであり、同じ値として書き込まれます。違いは、バイナリ出力にはテキストではない文字(NULLや0x01や0x02など)を含めることができる点です。 –

+0

@KenWhite私はそれが私を捨てたものだと思っています。私はたくさんのシンボルを期待していましたが、代わりに同じテキストを持っていました。入力いただきありがとうございます。 – ReMaKe

答えて

1

オブジェクトの生のメモリの内容を書き込むための正しい方法は次のようになります。

file.write(reinterpret_cast<char *>(&actors), sizeof(actors)); 

が、それはテキスト形式(ASCII)でファイルに出力します。

あなたの構造にはテキストのみが含まれているため、テキストは開いたときに表示されるものです。

また、16進エディタでファイルを開いていないと思います。これを行うと、各文字配列に含まれるテキストのスペースが少なくても、各フィールドが15バイトを占めることがわかります。フィールド間の余分なパディングバイトは、ファイルの内容を表示するために使用していたプログラムで印刷可能な文字として表示されないことがあります。このプログラムを与え例えば

、:

#include <iostream> 

struct celebrities 
{ 
    char name[15]; 
    char lastName[15]; 
}; 

int main() { 
    celebrities actors = { "Denzel", "Washington" }; 

    std::cout.write(reinterpret_cast<char *>(&actors), sizeof(actors)); 

    return 0; 
} 

がこれをコンパイルしてxxdにプログラムの出力をパイプには、以下を与える:

0000000: 4465 6e7a 656c 0000 0000 0000 0000 0057 Denzel.........W 
0000010: 6173 6869 6e67 746f 6e00 0000 0000  ashington..... 

各フィールドが正確に15バイトを占有します。ヌルストリングターミネーターの後の未使用スペースは、追加のヌル文字(バイト0)です。オブジェクトのフィールドのうちの長い文字列を以前に格納していた場合は、そのファイルの残りが出力ファイルに表示されることがあります。

我々#include <cstring>と直接上記のプログラムでstd::cout.write()への呼び出しの上にこの行を追加する場合:

std::strcpy(actors.lastName, "Whitaker"); 

は今のプログラムを実行するには、このコンテンツを生成します。左

0000000: 4465 6e7a 656c 0000 0000 0000 0000 0057 Denzel.........W 
0000010: 6869 7461 6b65 7200 6e00 0000 0000  hitaker.n..... 

注孤独n、以前の値 "ワシントン"の終わりから上がっています。

+0

その2番目のコードがうまくいきました。私はちょうどバイナリが実質的にシンボルと数字だと思っていましたが、基本的に出力が出てきました。私はそれをチェックするために16進エディタをダウンロードします。 – ReMaKe

+0

@ReMaKe技術的にバイナリファイル(実際にはすべてのファイル)には固有の意味はありません。彼らが有用であるためには内容を解釈する必要があります。 ASCIIとしてメモリに格納されたデータはASCIIで書き出されます(最初に別のものとしてエンコードされていない限り)ので、出力ファイルの内容はASCIIの各配列に格納されています。だから、ファイルはテキストのように見えます。なぜなら、それがそこに保存されているからです! 「私の出力」は、各バイトの16進コードを表示する16進ダンプツール*を介してパイプされたプログラムの出力*であることに注意してください。 – cdhowie

+0

私は参照してください。私はこの本で次の章で説明してくれると確信していますが、通常の出力ファイルの代わりにバイナリに出力したいという直接の理由はありますか? – ReMaKe

関連する問題