以涉及 fread 的条件退出程序

Exiting out of program with condition involving fread

我正在为我正在学习的课程开发照片提取程序。

对于这个程序,argv[1] 是我要从中提取图像的文件的名称。 jpg_name 与我提取的每个图像的名称有关;我正在尝试命名每个 jpg。数字从1开始。由于要提取50张照片,所以我想在提取完所有50张图像后停止程序。不幸的是,我的程序不确定何时终止,因此我认为 last 照片被多次覆盖,我不确定如何解决这个问题。然而,照片 1-49 结果没问题,只是照片 50 我有问题。

到目前为止,我尝试过的事情包括实现涉及 freadif 条件,如果程序无法将 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);
    }
}

如果我没理解错的话,您是想从一个 jpeg 文件中提取图像并将其拆分为多个文件。这里有几个问题需要思考

  1. fseek,为什么你需要它,除非你试图去到文件末尾以获得长度并返回到当前偏移量。否则,我建议您将其删除。
  2. 不需要两个freads。另外,如果 fread 给出的不是你想要的东西,feof() 应该告诉你是否已经达到 eof。

我稍微修改了你的代码,看看这是不是你要找的


    #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");
    }

您似乎对函数和 return 调用有基本的误解。我怀疑您认为: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
{
    ...