2017-03-17 5 views
0

私は自分のコードで何が起こっているのか理解しようと夢中になっています。CS50のセグメンテーションフォールトpset4

私は現在CS50のpset4にいます。挑戦を回復する。

about:about:about: 削除された写真がいくつかあるcard.rawというファイルがあります。私たちの仕事は、少しの法医学(idyllically)を行い、失われた写真を回復するプログラムを実装することです。

これによって、私は私のコードを添付:

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


int main(int argc, char *argv[]) 
{ 
    if (argc != 2) 
    { 

     fprintf(stderr, "Usage: ./recover file\n"); 
     return 1; 
    } 

    //declaring pointer infile and giving the address of argv[1]; 
    char *infile = argv[1]; 

    //Opening file 
    FILE *raw_data; 
    raw_data = fopen(infile, "r"); 

    //Checking for NULL error 
    if(raw_data == NULL) 
    { 
     fprintf(stderr, "Could not open file.\n"); 
     return 2; 
    } 


    uint8_t buffer[512];    //Delcaring unsigned int variable type. Array of 512 bytes. 
    int counter = 0;     //Declaring counter for counting jpegs files 

    FILE *outfile;     //Setting pointer named outfile for printing here 

    char filename[8];     //declaring 'filename' variable for storing the file's name 


    //While we can reads blocks of memory of 512 bytes from raw_data (aka the address from the infile) into buffer: 
    while (fread(buffer, 512, 1, raw_data)) 
    { 
     //Condition for tracking the first bytes that form a JPEG file 
     if(buffer[0] == 0xff && 
      buffer[1] == 0xd8 && 
      buffer[2] == 0xff && 
      (buffer[3] & 0xf0) == 0xe0) 
      { 


       if(counter == 0)        //If this is the 1st file, then name the file with 
                  //counter value with 3 digits (%03d) 
       {            
        sprintf(filename, "%03d.jpg", counter); // And 3 digits (%i3) 
        outfile = fopen(filename, "w");   //Open file named outfile in write mode 
        counter++; 
       } 

       else        //If this is not the first JPG opened, firstly close the 
       {         // current open file, and then open a new one with the 
        fclose(outfile);    // current counter value and 3 digits for its name 
        sprintf(filename, "%03d.jpg", counter); 
        outfile = fopen(filename, "w"); //Open file named 'outfile' in write mode 
        counter++; 

       } 


      } 

     fwrite(buffer, 1, sizeof(buffer), outfile); /* Write function that takes buffer data (aka the 
                 pointer to the array of elements to be written, 
                 writes 1 byte of elements of the syze buffer (512) 
                 and it writes it to the output, aka 'outfile' */ 
    } 
    fclose(outfile);   //Remember to close the last file once we get out of the while-loop 
} 

ここでトリッキーな部分です:

私はすべての問題の画像を正常に回復しました。 しかし、コードを何回か実行すると、たとえば5回、セグメンテーションフォルトが発生します。

私がcheck50を実行すると、次のメッセージが表示されます(いくつかの正常な実行とcheck50の予測の後にセグメンテーションフォルトの両方の画像を添付します)。 Click here to see the image

私はそれを得ることができません。私は記憶にいくつかの問題があるかもしれないが、私はそれが何であるか分かりません。

お世話になりました、ありがとうございました。 StackOVerFlowは常にガイダンスを求めるのに最適な場所です。

EDIT

セグメンテーションフォールトが促されたら、私はecho $?を実行した場合、私はちょうど@Thomasディッキーとして139

Here's the terminal prompt screenshot

EDIT

の値を取得オープンファイルを持っているかどうかにかかわらず、プログラムはファイルに書き込んでいたことが指摘されています。

自分のコードをよりきれいに保つためにコードを更新して修正しました。修正するためにif条件を追加しました。

はここソリューションです:

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


int main(int argc, char *argv[]) 
{ 
if (argc != 2) 
{ 

    fprintf(stderr, "Usage: ./recover file\n"); 
    return 1; 
} 

//declaring pointer infile and giving the address of argv[1]; 
char *infile = argv[1]; 

//Opening file 
FILE *raw_data; 
raw_data = fopen(infile, "r"); 

//Checking for NULL error 
if(raw_data == NULL) 
{ 
    fprintf(stderr, "Could not open file.\n"); 
    return 2; 
} 

uint8_t buffer[512];    //Delcaring unsigned int variable type. Array of 512 bytes. 

int counter = 0;     //Declaring counter for counting jpegs files 

FILE *outfile;     //Setting pointer named outfile for printing here 

char filename[8];     //declaring 'filename' variable for storing the file's name 


//While we can reads blocks of memory of 512 bytes from raw_data (aka the address from the infile) into buffer: 
while (fread(buffer, 512, 1, raw_data)) 
{ 
    //Condition for tracking the first bytes that form a JPEG file 
    if(buffer[0] == 0xff && 
     buffer[1] == 0xd8 && 
     buffer[2] == 0xff && 
     (buffer[3] & 0xf0) == 0xe0) 
     { 

      if(counter != 0)        
      {   
       fclose(outfile);      //If this is not the first JPG opened, close previous file 
      } 

      sprintf(filename, "%03d.jpg", counter); //print stream to 'filename' the value of 'counter' in 3 digits 
      outfile = fopen(filename, "w");   //Open file named outfile in write mode 
      counter++;        //Add 1 to counter 

     } 
     if(counter != 0)       //Don't start writing on a file until the first jpeg is found 
     { 
     fwrite(buffer, sizeof(buffer), 1, outfile);   /* - Write function that takes buffer data 
                    (aka the array of elements to be written) , 
                   - Write a block of 512 bytes of elements 
                    (aka the size of buffer), 
                   - 1 block of 512 bytes at a time, 
                   - And it writes it to the output, aka 'outfile' */ 
     }               

} 
fclose(outfile);   //Remember to close the last file once we get out of the while-loop 
return 0; 

}

+1

ありがとうございます。@A Busy Programmerがcタグを提案しました。私はSOFにとって非常に初心者ですので、私はすべてのルールに従うよう最善を尽くしています。 私はそれを感謝します! – Togeri

+0

問題はありません。あなたが今後ここに投稿しているコードの言語にタグを付けることを忘れないでください。それはあなたの質問に答えるより多くのユーザーを引き付けるでしょう。 –

+0

します。どうもありがとうございました! – Togeri

答えて

2

プログラムはヘッダだけは大丈夫に見える場合は、出力ファイルを開きますが、出力関わらずに書き込みます。 jpegヘッダーを持たないファイルを読むと、破損します。

+0

正確です。私は数日前に問題を修正しましたが、ここで解決策を投稿するのを忘れました。 これは私が@Thomas Dickeyを修正したものでした。それは私に大きな頭痛をもたらしましたが、やっとそれを行いました。ニースエラースポットの男、ありがとう! – Togeri

関連する問題