Fread прочитал неправильное количество допустимых байтов C

#c #fread #ppm

#c #fread #ppm

Вопрос:

Я прочитал два изображения ppm, и у меня есть структура, в которой хранится вся информация (магическое число, ширина, высота, уровень цветов и пикселей). Я считываю пиксели с помощью fread, но проблема в том, что нам нужно выполнить некоторый тест, чтобы проверить, является ли наш код допустимым и может ли создать новый ppm. Один тест должен быть недействительным (не создавать изображение, потому что количество пикселей отличается от заданного размера), но мой код все равно создает изображение, потому что в fread прочитанных успешных байтов должно быть 83 (условие выхода из кода заключается в том, что если количество байтов отличаетсяиз заданного размера (ширина * высота * 3) мы возвращаем 1 и останавливаем выполнение), но на самом деле он считывает 84 байта, что равно размеру, затем он продолжает выполнять код, вместо того, чтобы блокировать его, и я не понимаю, почему. Ошибка возникает после комментария к прочитанному пикселю. P.s Поскольку код работает, выдавая два изображения, я дважды даю одно и то же недопустимое изображение.

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

struct image
{
    char *magicNumber;
    int width;
    int height;
    int level;
    uint8_t *pixels;
};

int main(int argc, char *argv[])
{
    struct image img1;
    struct image img2;
    struct image img3;

    // Read files
    FILE *file1 = fopen(argv[1], "r");
    FILE *file2 = fopen(argv[2], "r");

    // Check files
    if (!file1 || !file2)
    {
        fprintf(stderr, "Error while opening the file.n");
        return 1;
    }

    // Alloc memory for pixels array
    img1.magicNumber = (char *)malloc(3 * sizeof(char));
    img2.magicNumber = (char *)malloc(3 * sizeof(char));

    // Take magic number
    fscanf(file1, "%s", img1.magicNumber);
    fscanf(file2, "%s", img2.magicNumber);

    // Check magic number
    if (strcmp(img1.magicNumber, "P6") != 0 || strcmp(img2.magicNumber, "P6") != 0)
    {
        fprintf(stderr, "Invalid magic number.n");
        return 1;
    }
    // Take width
    fscanf(file1, "%d", amp;img1.width);
    fscanf(file2, "%d", amp;img2.width);
    // Take height
    fscanf(file1, "%d", amp;img1.height);
    fscanf(file2, "%d", amp;img2.height);

    // Check size
    if (img1.width != img2.width || img1.height != img2.height)
    {
        fprintf(stderr, "Invalid Dimension.");
        return 1;
    }
    // Take level
    fscanf(file1, "%d", amp;img1.level);
    fscanf(file2, "%d", amp;img2.level);

    // Check level
    if (img1.level != 255 || img2.level != 255)
    {
        fprintf(stderr, "Invalid Level.");
        return 1;
    }
    // Alloc memory for pixels array
    img1.pixels = (uint8_t *)malloc(img1.width * img1.height * 3 * sizeof(uint8_t));
    img2.pixels = (uint8_t *)malloc(img2.width * img2.height * 3 * sizeof(uint8_t));

    // Read pixels
    size_t nrPixel1 = fread(img1.pixels, sizeof(uint8_t), img1.width * img1.height * 3, file1);
    size_t nrPixel2 = fread(img2.pixels, sizeof(uint8_t), img2.width * img2.height * 3, file2);

    // Check pixels read
    if (nrPixel1 != img1.width * img1.height * 3 || nrPixel2 != img2.width * img2.height * 3)
    {
        fprintf(stderr, "Invalid pixels.");
        return 1;
    }
  

Комментарии:

1. Не совсем уверен, что вы хотите, чтобы мы с этим делали. Если fread возвращает положительное число, которое не является переданным size*nmemb , значит, произошла ошибка или достигнут конец файла. Вы не проверяете наличие ошибок в обоих из двух fread вызовов. Вы должны лучше объяснить, чего вы пытаетесь достичь, и почему, по вашему мнению, это не работает, по вашей формулировке действительно трудно сказать. Кроме того, учтите тот факт, что код может быть правильным, но содержимое файла может быть нет.

2. Кроме того, примечание: fscanf(file1, "%s", img1.magicNumber); ожидается ли явное переполнение буфера. Используйте %2s вместо (да, 2, а не 3, терминатор добавляется автоматически) или лучше fgets() .

3. Смешивание методов чтения может привести к проблемам. Есть ли новая строка, оставшаяся во входном файле после fscanf() (которая считывает текст) и fread() (которая считывает двоичные данные)?

4. Также вы говорите: «во fread прочитанных успешных байтов должно быть 83». Как может быть 83 байта пиксельных данных? 83 — простое число.

5. Трудно сказать, правильно ли вы читаете, не имея под рукой точного файла, который вы пытаетесь прочитать, вызов fread выглядит правильным для меня, но вам могут не хватать некоторых байтов, которые не были прочитаны предыдущим вызовом fscanf as @WeatherVane notes . Вы должны это проверить.