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;
}
3 réponses
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.
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.
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);
^ ^
De nouvelles questions
c
C est un langage de programmation à usage général utilisé pour la programmation système (OS et embarqué), les bibliothèques, les jeux et les plateformes multiples. Cette balise doit être utilisée avec des questions générales concernant le langage C, tel que défini dans la norme ISO 9899 (la dernière version, 9899: 2018, sauf indication contraire - également balise les demandes spécifiques à la version avec c89, c99, c11, etc.). C est distinct de C ++ et il ne doit pas être combiné avec la balise C ++ en l'absence d'une raison rationnelle.