2

これは主に:

std::ofstream rainbow_file("rainbow.bin", std::ios::binary);
rainbow_file.write((const char*) p.pass, password::PASSWORD_SIZE);
rainbow_file.write((const char*) h.hash_, hash::HASH_SIZE);

どこ :

class hash
{
public:
    static const size_t HASH_SIZE = 32;
    uint8_t hash_[HASH_SIZE];
...
}
// similar for pass

Notepad++ で rainbow.bin ファイルを開くと、パスがパス (AZ、@、!、az、0-9 の文字) として表示され、ハッシュのバイナリ ガベージが表示されます。後で私がするとき:

std::ifstream rainbow_file("rainbow.bin", std::ios::binary);
rainbow_file.read((char*) p.pass, password::PASSWORD_SIZE);
rainbow_file.read((char*) h.hash_, hash::HASH_SIZE);

パスはバイナリのゴミとして返されます。私は多くのことを試しました(バイナリモードではない2つのストリームを開く、seekgを使用してファイルポインターを個別に移動する、さまざまなキャストを試すなど)が、私の人生ではこれを機能させることができません。そして、その理由がとても気になります。そして欲求不満。npp で繰り返しますが、すべてが順番に表示されます。

編集:これらは異なる制御フローであり、ストリームは適切にclosed()されています

Edit2:動作します!それを行うためのよりC ++の方法については、以下の回答とコメントを引き続き参照してください

4

2 に答える 2

1

非ASCII文字(バイナリファイルのようです)がファイルで使用されている場合は、std::noskipwsストリームマニピュレータを使用する必要があります。さらに、ロードする各フィールドの幅を明示的に指定して、結果のコードを指定することもできますrainbow_file >> std::noskipws >> std::setw ( password::PASSWORD_SIZE ) >> p.pass >> std::noskipws >> std::setw ( hash::HASH_SIZE ) >> h.hash_;

@Nicol Bolas uint_8tの型サイズについては何も想定していませんでしたが、ポインターのサイズについては想定していませんでした。ポインタのキャストは本質的に安全ではありませんが、型の実際のメモリ内レイアウトについて何を知っていますか?何もない。これが、非派生型のポインタをキャストすることが安全でない唯一の理由です。reinterpret_castを使用して、他の開発者やコンパイラーに自分が何をしているかを知っていることを知らせました。reinterpretcastは、日常の静的キャストと同じように機能します。誰もがそのトリックを見たことがわかるので、私は良い仕事をしました!

最後に、私はそれを繰り返す必要がp.pasありh.hash_、C++のポインタではありません!!!!!! それはPODです、Cスタイルのキャストはあなたに知らせることができません、C++スタイルはあなたに知らせることができます...

于 2012-05-28T21:48:16.210 に答える
1
std::ifstream rainbow_file("rainbow.bin", std::ios::binary);  /* OK */

rainbow_file.read((char*) p.pass, password::PASSWORD_SIZE);   /* KO */
rainbow_file.read((char*) h.hash_, hash::HASH_SIZE);

次のものに置き換える必要があります。

rainbow_file.read ( reinterpret_cast < char*> (&(p.pass)), password::PASSWORD_SIZE * sizeof(uint_8t));
rainbow_file.read ( reinterpret_cast < char*> (&(h.hash_)), hash::HASH_SIZE * sizeof(uint_8t));

この方法では、sizeof ( uint_8t ) == sizeof (char) を仮定しません。

C++ では、h.hash_ は型 uint_8t(&)[hash::HASH_SIZE] の配列であり、ポインターではありません...コンパイラーにキャストをチェックさせることで問題を簡単に見つけることができましたが、残念ながら、C スタイルを使用しましたチェックされていないキャスト。

C++ プログラムで C スタイルのキャスト メソッドを使用しないでください !!!

しかし実際には、純粋な C++ でエラーなしでそのように実行できます。

std::ifstream rainbow_file("rainbow.bin", std::ios::binary);

rainbow_file >> p.pass >> h.hash_;
于 2012-05-28T03:39:53.277 に答える