2017-03-22 3 views
-1

私はCS50 Pset4用の半加工コードを用意しています。あなたがそれを実行すると、27個のjpgファイルを回復することがわかりますが、最初の数行だけが表示されます。CS5Ox Pset4リカバリ:コードは部分画像のみを復元します

誰かが私を正しい方向に向けることができますか?

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

typedef uint8_t BYTE; 

int main (int argc, char *argv[]) 
{ 
    // ensure proper usage 
    if (argc != 2) 
    { 
     fprintf(stderr, "Usage: ./recover infile\n"); 
     return 1; 
    } 

    // open file to be recovered 
    FILE *infile = fopen(argv[1], "r"); 
    if (infile == NULL) 
    { 
     fprintf(stderr, "Could not open infile.\n"); 
     return 2; 
    } 

    // temp storage for blocks 
    BYTE buffer[512]; 

    // variable to store filename 
    char filename[8]; 

    //store number of recovered files 
    int n = 0; 

    // temp storage for outfiles 
    FILE* outfile = NULL; 

    // iterate over all blocks of memory until end of SD card is reached 
    while (fread(buffer, 512, 1, infile) != 0) 
    { 
     // read one block 
     fread(buffer, 512, 1, infile); 

     // check if block is start of jpeg 
     if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) 
     { 
      //close previous file if already open 
      if(outfile != NULL) 
      { 
       fclose(outfile); 
      } 

      // creeate new outfile 
      sprintf(filename, "%03i.jpg", n); 
      outfile = fopen(filename, "w"); 

      // write block to outfile 
      fwrite(buffer, 512, 1, outfile); 

      n++; 
     } 
     else 
     { 
      // write block to current outfile 
      if(outfile != NULL) 
      { 
       fwrite(buffer, 512, 1, outfile); 
      } 
     } 
    } 

    //close last outfile 
    fclose(outfile); 

    //close infile 
    fclose(infile); 
} 
+0

あなたの 'filename'は短すぎます(null-termination?)。それに複数の時間を費やして...まあ、少し無駄です。 –

+0

@Eugene、仕様ファイル名はXXX.jpgである必要があります。 null-terminationを考えると、私はファイル名を格納するのに8文字が必要だと思うでしょう。または私は何か明白な行方不明ですか? (私は以前の経験値0でcs50を開始しました:)) – LegalExperience

+0

@マーク、私の出力の例をここに見つけることができます:http://imgur.com/3Nf1Ui4。出力がどのように表示されるべきかはわかりませんが、明確な画像でなければなりません。 – LegalExperience

答えて

0

この問題を引き起こす可能性のあることがいくつか表示されます。

まず、nカウンターの注文を確認してください。実際に新しいファイルへの書き込みを開始する前に、カウンタを追加する必要がありますが、これは好みの問題であり、コードのクリーンアップの仕方です。

第二に、次のコードを使用してelse条件を代用してみてください:

if(outfile != NULL)       
     { 
     fwrite(buffer, 512, 1, outfile); 
} 

:私はif条件のためのあなたのelse条件を置換しましたことを心に留めておいてください。これは、最初の条件が満たされたときに、この条件を実行して「ブロックから飛び出す」ためです。したがって、elseは実行され、最初のifの条件は実行されません。 elseの状態を維持したい場合は、コード内で行ったように、別のifをネストする必要があります。

elseifに置き換えると、jpgの最初の3バイトの値に関係なく(つまり、0x00、0xff、0x00に関係なく)常にチェックされます。わかりやすいコード。

最後に、もっと重要なのは、同じ操作で同じファイルに2回書くのはなぜですか? n++カウンターの下にあるfwrite()機能に注意してください。本当に必要ですか?言い換えれば

:この行を削除します。

// read one block fread(buffer, 512, 1, infile);

を他の間違い、あなたが二回あなたのファイルを読んでいるということです、そしてすべてのステップで二回事前ので、あなたは半分の情報を取得します。 これはイメージの半分(27程度)を取得している理由です。

消去の2行:私が言ったように

// read one block fread(buffer, 512, 1, infile);

、読み、あなたのファイル以内に2回書き込むことによって、あなたは情報の半分を取得します。これはあなたがあなたのイメージを無意識の色(私が推測する)とイメージファイルの半分に色づけしてしまう曖昧な方法につながります。

あなたのコードと私があなたに提供した固定ソリューションでcheck50 2016.recover recover.cを実行し、CS50のcheck50からすべてのチェックを渡しました。時間をかけて、プログラムの中の重要な部分である制御フローやポインタの使用法など、プログラムのすべてについて考えてください。

これまでの経験なしにCS50を起動するのは難しいことがあります。がんばり続ける。すでに5週目になっています。

+1

ありがとうございます!これは本当に役に立ちました。私はwhileループ状態のfreadもポインタを進めたことに気付かなかった。私のコードを変更し、check50を渡しました。 5週目に! :D – LegalExperience

関連する問題