Магическое число в файлах. C программирование

Я хочу получить Magic Number из двоичного файла. Например, файлы JPG содержат FFD8 для магического числа в первых байтах. Как я могу это прочитать? Я хочу написать программу, которая проверяет, отвечает ли расширение файла на магическое число, и если оно не переименовывает файл.

Я думаю, так и должно быть, но это не работает. Он всегда печатает разные значения. Я хочу, чтобы он дал мне магический номер, если файл JPG, то - FFD8.

int main()
{
    FILE *f;
    char fName[80];
    char *array;
    long fSize;

    printf("Input file name\n");
    scanf("%s", fName);
    if((f=fopen(fName, "rb"))==NULL)
    {
        fprintf(stderr, "Error\n");
        exit(1);
    }

    fseek (f , 0 , SEEK_END);
    fSize = ftell (f);
    rewind (f);
    array=(char *)malloc(fSize+1);

    fread(array, sizeof(char), 4, f);
    printf("%x", array);
    free(array);
}

person Community    schedule 25.04.2014    source источник
comment
Есть ли какая-то причина, по которой вы чувствуете себя обязанным определить размер всего файла и сделать буфер достаточно большим, чтобы его вместить, когда на самом деле вам нужны только четыре байта и копируются они? И если да, то понимаете ли вы, что файловая система с радостью сообщит вам размер файла простым fstat()?   -  person EOF    schedule 26.04.2014
comment
Я впервые использую бинарные файлы, поэтому захотелось попробовать что-то новое. Однако не могли бы вы рассказать мне больше о fstat (), потому что я ничего не могу найти об этом.   -  person    schedule 26.04.2014
comment
Что ж, fstat() находится не в стандарте C, а в POSIX, хотя я почти уверен, что есть эквиваленты в других семействах ОС. Чтобы использовать fstat(), вы создаете struct stat x, а затем вызываете f-/l-/stat() для файла-дескриптора / -name и x. Тогда вы посмотрите на x.st_size.   -  person EOF    schedule 26.04.2014


Ответы (1)


printf("%x", ...) ожидает int аргумент, а вы даете ему char *, то есть указатель. Это неопределенное поведение.

Вы, вероятно, имели в виду

printf("%02hhx%02hhx%02hhx%02hhx\n", array[0], array[1], array[2], array[3]);

для печати первых 4 символов в виде шестнадцатеричных чисел. (Спасибо @chux за напоминание о модификаторе "hh", который указывает, что преобразование применяется к подписанному или беззнаковому аргументу char.)

(Но обратите внимание, что «FFD8» - это шестнадцатеричная запись для двух байтов: 0xFF, 0xD8.)

person Martin R    schedule 25.04.2014
comment
Вы можете сказать мне, что означает 02? И я получаю от этого ffffffffffffffd8ffffffffffffffe0. Любые идеи? - person ; 25.04.2014
comment
@ user3476022: объявите свой массив как unsigned char *array;, тогда вы получите правильный результат. 02 означает, что каждое число печатается с двумя цифрами, например 00, 01, FF. - person Martin R; 25.04.2014
comment
Спасибо тебе, друг. Буду признателен, если вы объясните, почему он работает только с неподписанными? Я новичок и впервые работаю с hex. - person ; 25.04.2014
comment
@ user3476022: аргументы printf array[i] преобразуются в целые числа. Если char является типом подписью на вашей платформе, тогда 0xD8 является отрицательным числом и будет преобразовано в целое число 0xFFFFFFD8 (это называется расширением знака, если вы хотите найти его ). - person Martin R; 25.04.2014
comment
Можно использовать "%02hhx" и не беспокоиться о расширении знака. - person chux - Reinstate Monica; 25.04.2014
comment
@chux: Вы совершенно правы, я забыл об этом. Ответ обновлен. - person Martin R; 25.04.2014