Basi c - Управление памятью с помощью C - PullRequest
0 голосов
/ 17 марта 2020

Я начинаю учиться C, и я определенно не очень хорош в этом, я прохожу курс CS50, неделя 4 (Память), и я должен изучить .raw для .jpeg .

Когда я запускаю свой код, изображения создаются идеально, по порядку, бла-бла-бла, но когда я их открываю, они пусты (у некоторых часть изображения, но не то, чего я хочу достичь),

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

void makeJPEG(int nof, unsigned char chunk[512]);

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Just give 1 argument, not less, not more.\n");
        return 1;
    }
    printf("El nombre del archivo es -> %s\n", argv[1]);
    FILE *file = fopen(argv[1], "r");
    if (file == NULL)
    {
        return 1;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    unsigned char chunk[512];
    int nof = 0;
    while (fread(chunk, sizeof(char), 512, file) == 512)
    {
        if (sizeof(chunk) == (sizeof(char) * 512))
        {
            if (chunk[0] == 0xff && chunk[1] == 0xd8 && chunk[2] == 0xff)
            {
                printf("\n****************************************************\n");
                printf("\n\nProbably a JPEG\n");
                if ((chunk[3] & 0xf0) == 0xe0)
                {
                    printf("Definitely a JPEG\n");
                    char filenameMain[8];
                    makeJPEG(nof, chunk[512]);
                    sprintf(filenameMain, "%03i.jpg", nof);
                    printf("The file -> %s <- was created successfully\n\n", filenameMain);
                    printf("\n****************************************************\n");
                    nof++;
                }
            }
            else
            {
                printf("Not a JPEG\n");
            }
        }
    }
    fclose(file);
    printf("\n*Final*\n");
    return 0;
}

void makeJPEG(int nof, unsigned char chunk[512])
{
    FILE* img = NULL;
    //Declaring a String of 8 bytes
    char filename[8];

    //Giving that String the name of the file
    sprintf(filename, "%03i.jpg", nof);

    //Writing the new jpg file
    img = fopen(filename, "a");
    fwrite(chunk, sizeof(char), 512, img);

    //Closing the image and freeing the memory
    fclose(img);
}

Я думаю, что моя проблема в том, как я использую переменную "chunk" и как я отправляю ее в "makeJPEG", но я понятия не имею, что я делаю неправильно, повторяю, я совершенно новичок.

PS: извините за ошибки в моем Engli sh и спасибо за помощь заранее:)

1 Ответ

1 голос
/ 17 марта 2020

makeJPEG(nof, chunk[512]); неверно. Это пытается передать элемент 512 chunk. Измените его на makeJPEG(nof, chunk);. Это передает буфер chunk (по указателю). Ваш компилятор должен был дать вам предупреждение об этом. Если этого не произошло, включите предупреждающие сообщения и обратите на них внимание.

Основной l oop вашей программы продолжает чтение из файла в chunk и проверяет каждое из них на наличие JPEG , Это не правильно. Только первая часть файла будет иметь индикаторы того, что это JPEG. Чтобы скопировать весь файл, вы должны проверить только первую часть, а затем скопировать всю.

Кроме того, l oop увеличивает nof, и makeJPEG открывает новый файл каждый раз, когда он называется. Это позволит записать каждый кусок входного файла во множество различных выходных файлов, что, как правило, бесполезно. Если вы хотите, чтобы ваша программа скопировала один файл JPEG, перепроектируйте его так, чтобы куски записывались в один и тот же файл каждый раз, а не в новый файл. Если вы хотите, чтобы ваша программа обрабатывала много входных файлов, вам нужно изменить ее другими способами.

Это бесполезно: sizeof(chunk) == (sizeof(char) * 512). Размер chunk всегда равен размеру, который был определен, 512 байт.

Это необходимо изменить: fread(chunk, sizeof(char), 512, file) == 512. Вам необходимо использовать result = fread(chunk, sizeof chunk, 1, file), где result ранее объявлено с типом size_t. Тогда вам нужно проверить result. Если это 512 байт, у вас есть полный блок, и вы должны записать его в выходной файл и l oop для обработки большего количества фрагментов. Если он равен нулю, данные больше не могут быть прочитаны, и вы закончили с этим файлом (кроме особых обстоятельств, которыми мы можем пока пренебречь). Если оно находится между 0 и 512, вы получите частичный фрагмент, который, вероятно, является концом файла. Вам следует записать его в выходной файл, после чего вы закончите работу с этим входным файлом (за исключением особых обстоятельств).

...