1

Тема: Відновлення стертих фото, pset4, cs50.

Доброго дня. Настав час мого першого повідомлення на цьому форумі.
Суть проблеми: роблю я домашню роботу 4 (pset4) з курсу CS50 (https://x.cs50.net/2012/psets/4/pset4.html). В останньому пункті (CSI) треба написати програму recover.c, яка б відновляла випадково стерті фото у форматі .jpg (з файлу card.raw). Я її спробувала написати, але чомусь вона не працює :-). Перевіряючи на gdb у мене виникло враження, що інформація з файлу абсолютно не зчитується в буфер і я не розумію чому (пам'яті у буфері якраз повинно вистачати). Буду дуже рада якійсь підказці.

Ось мій код:

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

int main(void)
{
    //open card.raw
    FILE* fp1 = fopen("card.raw", "r");
    
    //int to keep track of number of jpg's
    int i = 0;
    
    while(1)
    {   
        //buffer for reading in it
        char* b = malloc(512*sizeof(char));
    
        //reading of the information in the input file
        fread(b, 512, 1, fp1);
        
        //looking for the end of card.raw 
        if(feof(fp1))
            break;
        
        if((atoi(&b[0]) == 0xff && atoi(&b[1]) == 0xd8 && atoi(&b[2]) == 0xff && atoi(&b[3]) == 0xe0) ||
            (atoi(&b[0]) == 0xff && atoi(&b[1]) == 0xd8 && atoi(&b[2]) == 0xff && atoi(&b[3]) == 0xe1))
        {            
            //creating the name of the jpg
            char name[8];
            printf("%.3i.jpg", i);
            sprintf(name, "%.3i.jpg", i);
            name[7] = '\0';
            i++;
            
            //opening jpg
            FILE* fp = fopen(name, "w");
            
            //writing info to jpg
            fwrite(b, 512, 1, fp);
            
            //closing output file
            fclose(fp);
        }
        else
        {
            //skipping first blocks of bytes
            if(i != 0)
            {
                
                //recreating name for a output file   
                char name[8];
                sprintf(name, "%.3i.jpg", i-1);
                name[7] = '\0';
                
                //opening jpg
                FILE* fp = fopen(name, "a");
                
                //writing info to jpg
                fwrite(b, 512, 1, fp);
                
                //closing output file
                fclose(fp); 
            }           
        }
        
        //freeing memory
        free(b);
    }
    
    return 0;
}

P.S.: Не судіть строго, це мій перший курс по Computer Science.

Подякували: Replace1

2

Re: Відновлення стертих фото, pset4, cs50.

atoi перетворює рядок з десятковим числом (наприклад "123") на число.
Чомусь мені здається, що

atoi(&b[0]) == 0xff && atoi(&b[1]) == 0xd8

працює не зовсім там, як ви задумали... принаймні, мені важко уявити собі десяткове число, яке повністю дорівнює 255, а без першої цифри - 216.

3

Re: Відновлення стертих фото, pset4, cs50.

Логічно буде, коли цикл побудувати як

while (!feof(fp))
{
char* b = malloc(512*sizeof(char));
    
        //reading of the information in the input file
        fread(b, 512, 1, fp1);
        //і т.д.
}
I belong to the Dead Generation.

4

Re: Відновлення стертих фото, pset4, cs50.

Дякую за допомогу. Про atoi я теж думала, що не буде працювати, але оскільки проблема з'являлась на етапі fread, то я про atoi ще не задумувалась.
Щоб програма запрацювала, я зробила 2 зміни.
1) char* b змінила на uint8_t. Я так розумію, що це і було причиною чому fread не працював.
2) ну і прибрала atoi, замість цього перевіряла напряму b[0] == 0xff...

5

Re: Відновлення стертих фото, pset4, cs50.

Bartash написав:

Логічно буде, коли цикл побудувати як

while (!feof(fp))
{
char* b = malloc(512*sizeof(char));
    
        //reading of the information in the input file
        fread(b, 512, 1, fp1);
        //і т.д.
}

У такому випадку буде копіюватись один зайвий "кусок інформації, оскільки спочатку йде перевірка eof на даний момент, а тоді копіювання інформації і переміщення "вказівника". І коли переміщується вказівник якраз можна отримати eof, але ми цього знати не будемо, і таки запишемо цей блок в output file.

6

Re: Відновлення стертих фото, pset4, cs50.

Н.м.д., немає сенсу кожного разу виділяти пам'ять, а потім звільняти. Так що

char* b = malloc(512*sizeof(char));
int b_size;

        //while reading of the information in the input file
while ( 0 != (b_size = fread( b, 512, 1, fp1 ) )
{
...

або навіть (якщо розмір точно має бути кратний 512)

        //while reading of the information in the input file
while ( fread( b, 512, 1, fp1 ) == 512 )
{
...