1

このバイナリ リーダーは、インターネットでのチュートリアルの後に作成しました。(リンク先を探しています…)

このコードはファイルを 1 バイトずつ読み取り、最初の 4 バイトはまとめてマジック ワードです。(MAGIとしましょう!)私のコードは次のようになります:

std::ifstream in(fileName, std::ios::in | std::ios::binary);
char *magic = new char[4];

while( !in.eof() ){
   // read the first 4 bytes
   for (int i=0; i<4; i++){
      in.get(magic[i]);
   }

   // compare it with the magic word "MAGI"
   if (strcmp(magic, "MAGI") != 0){
        std::cerr << "Something is wrong with the magic word: " 
                  << magic << ", couldn't read the file further! " 
                  << std::endl; 
        exit(1);
    }

   // read the rest ...
}

ここで問題が発生します。ファイルを開くと、次のエラー出力が表示されます。 Something is wrong with the magic word: MAGI?, couldn't read the file further!つまり、この例の文字のように、MAGI という単語の後に常に 1 つの (ほとんどランダムな) 文字があります?。C++ の文字列がどのように格納され、相互に比較されるかに関係があると思います。私は正しいですか、どうすればこれを回避できますか?

PS: この実装は別のプログラムに含まれており、まったく問題なく動作します ... 奇妙です。

4

1 に答える 1

3

strcmp は、両方の文字列がヌル文字で終わる (ヌル文字で終わる) と想定します。この場合のように、終端されていない文字列を比較する場合は、strncmpを使用して、比較する文字数 (この場合は 4) を指定する必要があります。

if (strncmp(magic, "MAGI", 4) != 0){

strcmp を使用して null で終了していない char 配列を比較しようとすると、配列の長さがわからない (C/C++ では、配列自体を見ただけでは配列の長さがわからない - 必要がある)標準ライブラリはこの制限を免除されていません)。そのため、char 配列の後にたまたまメモリに格納されたデータを、0 バイトに達するまで読み取ります。

ところで、Lightness Races in Orbitによる質問へのコメントに注意してください。これは、現在抱えている問題とは関係ありませんが、後で問題を引き起こす可能性のある別のバグを示唆しています。

于 2012-11-14T16:00:36.283 に答える