Выход из программы с условием fread - PullRequest
0 голосов
/ 14 июля 2020

Я работаю над программой извлечения фотографий для курса, который я изучаю.

Для этой программы argv [1] - это имя файла, из которого я хочу извлечь изображения. jpg_name относится к имени каждого изображения, которое я извлекаю; Я пытаюсь назвать каждый файл jpg. численно, начиная с 1. Поскольку нужно извлечь 50 фотографий, я хотел бы остановить программу после того, как все 50 изображений будут извлечены. К сожалению, моя программа не знает, когда завершить работу, и поэтому я считаю, что фотография последняя перезаписывается несколько раз, и я не уверен, как это исправить. Тем не менее, фотографии 1-49 получаются нормально, это просто фотография 50, с которой у меня проблема.

То, что я пытался до сих пор, включает выполнение условия if, включающего fread где, если программа не может чтобы прочитать 512 байт кода в массив, он завершится. К сожалению, это тоже не работает. Приветствуются любые предложения:

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

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Invalid entry.\n");
        return 0;
    }

    int counter = 1;
    FILE* images;
    char jpg_name[8];

    // Check if bytes are jpg. signatures.
    for (int n = 0; counter < 51; n = n + 512)
    {
        // Open file for reading.
        FILE *file = fopen(argv[1], "r");
        if (!file)
        {
            return 1;
        }

        unsigned char array[512];
        fseek(file, n, SEEK_SET);
        fread(array, 1, 512, file); // if EOF, won't have 512 to write into!!!
        if (fread(array, 1, 512, file) != 512)
        {
            return 2;
        }

        if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
        {
            // Convert integer to string and store into jpg character array. Increment image number.
            sprintf(jpg_name, "%03i.jpg", counter);
            counter++;

            // Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
            images = fopen(jpg_name, "a");
            fwrite(array, 1, 512, images);
            fclose(images);
        }
        else // If 1st 4 bytes aren't jpg signature.
        {
            if (counter > 1)
            {
                images = fopen(jpg_name, "a");
                fwrite(array, 1, 512, images);
                fclose(images);
            }
        }
        fclose(file);
    }
}

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Похоже, вы имеете базовое c непонимание функций и обратных вызовов. Я подозреваю, что вы думаете: инструкция fread читает данные, а инструкция if проверяет, правда ли что-то. Итак, вы читаете данные, а затем проверяете, сколько было прочитано. Однако вы упускаете из виду тот факт, что if выполняет инструкции внутри (), чтобы увидеть, верен ли результат. Таким образом, if(fread(array, 1, 512, file) != 512) читает данные , а проверяет результат.

Если вы хотите прочитать данные и проверить результат, используйте if(fread(array, 1, 512, file) != 512). Если вы хотите читать данные, а не проверять результат, используйте fread(array, 1, 512, file);. Не используйте оба.

Вы также можете использовать переменную, например:

int number_of_bytes_read = fread(array, 1, 512, file);
if(number_of_bytes_read != 512) // this doesn't read data, it just gets the number from the variable
{
    ...
0 голосов
/ 14 июля 2020

Если я правильно понял, вы пытаетесь извлечь изображения из одного файла jpeg и разбить его на несколько файлов. Вот несколько вопросов, на которые следует подумать о

  1. fseek, зачем вам это, если вы не пытаетесь go до конца файла для длины и возврата к текущему смещению. В противном случае советую удалить его.
  2. Два фреда не требуются. Кроме того, feof () должен сообщить вам, достигли ли вы eof, если fread дает что-то другое, кроме того, что вы ищете.

Я немного отредактировал ваш код, посмотрите, это то, что вы ищете


    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
        if (argc != 2)
        {
            printf("Invalid entry.\n");
            return 0;
        }
    
        int counter = 1;
        FILE* images;
        char jpg_name[8];
        int num = 0;
        int total_num = 0;
    
        // Check if bytes are jpg. signatures.
        for (int counter = 0; counter < 51; counter ++)
        {
            // Open file for reading.
            FILE *file = fopen(argv[1], "r");
            if (!file)
            {
                printf("Exiting at 1\n");
                return 1;
            }
    
            unsigned char array[512];
            // don't understand why you need this ? unless, you are trying to go to end of file and get back to the current
            // offset
            fseek(file, 0, SEEK_SET);
            total_num = 0;
            while((num = fread(array, 1, 512, file)) == 512)
            {
                if (array[0] == 0xff && array[1] == 0xd8 && array[2] == 0xff && (array[3] & 0xf0) == 0xe0)
                {
                    // Convert integer to string and store into jpg character array. Increment image number.
                    sprintf(jpg_name, "%03i.jpg", counter);
                    counter++;
    
                    // Open images file to write into, allocate memory to jpg file to write into, write 512 bytes from array into image file.
                    images = fopen(jpg_name, "a");
                    fwrite(array, 1, 512, images);
                    fclose(images);
                }
                else // If 1st 4 bytes aren't jpg signature.
                {
                    if (counter > 1)
                    {
                        images = fopen(jpg_name, "a");
                        fwrite(array, 1, 512, images);
                        fclose(images);
                    }
                }
            }
            fclose(file);
        }
        printf("Exiting here\n");
    }

...