Il s'agit de Recover from pset4 CS50. Il n'y a pas d'erreur lorsque je le compile. Lorsque j'exécute le code, j'obtiens une erreur de segmentation. Je ne comprends pas exactement quelle est l'erreur. J'ai recherché des solutions liées aux questions sur l'erreur de segmentation postées par d'autres mais elles ne semblent pas résoudre mon problème.

Quelqu'un peut-il expliquer ce qui ne va pas et comment le résoudre.

#include <stdio.h>
#include <stdint.h>
typedef uint8_t BYTE;

int main(int argc, char *argv[])
{

if (argc != 2)
{
    printf("Usage: ./recover image\n");
    return 1;
}

FILE *inFile = fopen(argv[1], "r");
if(!inFile)
{
    printf("Could not open file!\n");
    return 1;
}

BYTE buffer[512];
FILE *outFile = NULL;
int imageNum = 0;
char fileName[8];

while (!feof(inFile))
{
     fread(buffer, 1, sizeof(buffer), inFile);
     if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[4] & 0xf0) == 0xef0)
     {
         if (imageNum > 0)
         {
            fclose(outFile);
         }
         imageNum++;
         sprintf(fileName, "%03i.jpg", imageNum);
         outFile = fopen(fileName, "w");
     }
    if (outFile != NULL)
    {
        fwrite(buffer, 1, sizeof(buffer), outFile);
    }
}
fclose(outFile);
fclose(inFile);
return 0;
}
1
Zara K 2 juin 2020 à 16:09

3 réponses

Meilleure réponse

J'ai trouvé la solution au problème ci-dessus en modifiant ces lignes de code

while (!feof(inFile)) 

À

while (fread(buffer, sizeof(buffer), 1, inFile))

Et

fread(buffer, 1, sizeof(buffer), inFile);
fwrite(buffer, 1, sizeof(buffer), outFile);

À

fread(buffer, sizeof(buffer), 1, inFile);
fwrite(buffer, sizeof(buffer), 1, outFile);

Le problème principal était également dans mon état si j'ai changé de

if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[4] & 0xf0) == 0xef0)

À

 if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)

Et le dernier changement

imageNum++;
sprintf(fileName, "%03i.jpg", imageNum);
outFile = fopen(fileName, "w");

À

sprintf(fileName, "%03i.jpg", imageNum);
outFile = fopen(fileName, "w");
imageNum++;

Merci à tous pour vos suggestions et votre aide.

1
Zara K 4 juin 2020 à 08:17

fileName est défini pour avoir huit éléments dans char fileName[8];, mais sprintf(fileName, "%03i.jpg", imageNum); écrit plus de huit caractères une fois que imageNum dépasse 999.

0
Eric Postpischil 2 juin 2020 à 13:28

La raison du segfault est probablement cette déclaration:

char fileName[8];

Pour les noms de fichiers supérieurs à 999, fileName débordera.

C'est-à-dire pour imagenum >= 1000

sprintf(fileName, "%03i.jpg", imageNum);//produces 8 characters + NULL == 9

... produira "1000.jpg" qui est un buffer overflow, donc segfault.

Rendre fileName plus grand est la solution:

char filename[20];//or larger as needed.

Aussi ,
selon les définitions de fwrite () et fread (), les arguments de fonction suivants sont mal placés:

fread(buffer, 1, sizeof(buffer), inFile);
fwrite(buffer, 1, sizeof(buffer), outFile);
               ^        ^

Devrait être:

fread(buffer, sizeof(buffer), 1, inFile);
fwrite(buffer, sizeof(buffer), 1, outFile);
                     ^         ^
1
ryyker 2 juin 2020 à 15:57