2016-08-10 10 views
-4

私はCを学ぶためにハーバード大学からEDx CS50クラスを受け取りました。私は問題セットの1つに私のコードが変わったことに気付きました。元のものがなぜそうでないのか理解したい)。この割り当ての考え方は、JPEGファイルへの参照が削除されたファイルをチェックして、メモリから写真を復元することです。fopenはCの変数値を変更します

私が持っている問題は、以下のfoundJPEGブール値です。私の最初のアイデアは、最初の写真が見つかるまでそれをfalseに設定し、それから個々のファイルを書き始める(連続したメモリブロックになるはずだった)。 jpegヘッダーが初めて検出されると、新しい書き込みファイルが生成され、新しいjpegが見つかるまでその情報がコピーされます。さらに、foundJPEG変数はtrueになります。もともと私はif(foundJPEG)コードブロックのelse節の下でこの宣言をしていましたが、実行した後にfopen関数が呼び出されるたびに変数はfalseに戻りました。したがって、変数がすでにtrueに変更されている場合でも、新しいファイルを開いた後で、新しいfoundJPEG = true;ステートメントを追加しました。

fopenが呼び出されるたびにブール値がfalseになっている理由を知りたいと思います。特に、Cはメモリの割り当てを非常に制御しているので、ファイルを開くたびに、あるいは範囲の問題のために何らかの形で上書きされていたかどうかは疑問でした。おそらくこれはルーキーミスだと思いますが、誰かがこれを理解しやすくするために、より大きなアプリケーションを書くときにミスを混乱させないように考えていたかもしれません。どうもありがとうございました!

/* 
* recover.c 
* 
* Computer Science 50 
* Problem Set 4 
* 
* Recovers JPEGs from a forensic image. 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <stdbool.h> 

typedef uint8_t BYTE; 


int main(int argc, char* argv[]) { 
    int k = 0; 
    bool foundJPEG = false; 
    char title[7]; 
    FILE* file = fopen("card.raw", "rb"); 
    FILE* img; 

    BYTE buf[512]; 
    int size = sizeof(buf); 
    while(fread(&buf, size, 1, file) == 1) { 
     if(buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff && buf[3] >= 0xe0 && buf[3] <= 0xef) { 
      if(foundJPEG) { 
       fclose(img); 
       k++; 
       sprintf(title, "%03d.jpg", k); 
       img = fopen(title, "wb"); 
       foundJPEG = true; 
      } 
      else { 
       sprintf(title, "%03d.jpg", k); 
       img = fopen(title, "wb"); 
       foundJPEG = true; 
      } 


     } 
     if(foundJPEG) { 
      fwrite(&buf, size, 1, img); 
     } 

    } 

    fclose(img); 
    return 0; 
} 
+0

問題を1つまたは2つに圧縮できますか?小説を読むことは楽しいことではありません。 –

+1

imgが一度も定義されていないときは、最初にfclose(img)を呼び出すときに、未定義の動作があると思います。さらに、ifおよびelse foundJPEGテストで厳密に同一のコードブロックがあります。 –

+0

@self申し訳ありませんが、ここで初めて質問を書いています。基本的に、私はそのコードブロックでfopen関数がfoundJPEGブール値の値を変更する理由を知りたいと思います。 – Sraffa

答えて

1

コードには少なくとも2つの動作があります。

fclose(img); 

あなたはsprintfのは、あなたのスタック上に何か他のものを上書きします7バイトのバッファに8文字3 + 4 +ヌルターミネータを書き込みます初期化されていない

char title[7];   
sprintf(title, "%03d.jpg", k); 

IMGでこれを呼び出しています。

これらの原因の1つが問題の原因です。

+0

ありがとう!あなたは正しいです、私はタイトル配列のヌルターミネーターについて忘れていました:(。imgのことについては、今からNULLに初期化する必要があると思います。 – Sraffa

関連する問題