Извлечение последних 128 байтов из двоичного файла с помощью C - PullRequest
2 голосов
/ 23 сентября 2011

Я делаю редактор тегов id3 на языке C. У меня проблемы с выяснением того, как извлечь последние 128 байтов из конца двоичного файла, чтобы манипулировать / распечатывать область, в которой находится тег id3. Вот какой-то код:

struct Tag{
    char tagMark[3];
    char trackName[30];
    char artistName[30];
    char albumName[30];
    char year[4];
    char comment[30];
    char genre;
};

int main(int argc, char *argv[]){
    struct Tag fileTag;
    FILE *fp;
    fp=fopen(argv[0], "r+b");
    if(!fp){
        printf("ERROR: File does not exist.");
    }

    int bufLength=129;
    fseek(fp, 0, SEEK_END);
    long fileLength=ftell(fp);
    fseek(fp, fileLength-bufLength+1, SEEK_SET);
    fread(&fileTag, sizeof(fileTag), 1, fp);

    printf("%s\n", fileTag.tagMark);
    return 0;
}

Я использую файл для проверки, который содержит правильно отформатированный тег id3. В теге id3 первые три байта содержат «T», «A» и «G» соответственно, чтобы идентифицировать, что тег существует. Кто-нибудь знает, почему, когда я запускаю эту программу, "_main" - единственное, что печатает?

Ответы [ 2 ]

5 голосов
/ 23 сентября 2011

Используйте fseek() (или lseek(), если вы используете файловые дескрипторы вместо файловых потоков) с отрицательным смещением (-128) байтов от концафайл.Затем прочитайте 128 байтов информации.

Следовательно:

fseek(fp, -128L, SEEK_END);
lseek(fd, -128L, SEEK_END);

(Интересно, что макросы SEEK_END, SEEK_SET и SEEK_CUR определены в обоих <stdio.h> для стандартногоC и <unistd.h> для POSIX.)

4 голосов
/ 23 сентября 2011

Ваша программа делает

fp=fopen(argv[0], "r+b");

argv [0] содержит имя запущенного исполняемого файла, вы хотите argv[1], первый параметр командной строки. Следующая проблема, с которой вы, вероятно, столкнетесь (при запуске с ID3v2), - выравнивание полей структуры, в зависимости от используемых типов данных, компилятор может оставить «пробелы» между последовательными элементами структуры. Чтобы избежать этой проблемы, компилятору следует дать указание выровнять структуру по границам байтов с (в большинстве случаев проверьте документацию вашего компилятора)

#pragma pack(1) 

Этот Структура заполнения и упаковки ТАК ответ ясно объясняет, что происходит, если вы не используете правильную упаковку.

Также см. макет ID3V1 , после отдельных полей не всегда есть завершающий 0, поэтому

printf("%s\n", fileTag.tagMark);

напечатает TAG, за которым следует название песни (printf% s останавливается только при обнаружении \ 0).

ИМХО, учитывая джунгли, что ID3 - это, вероятно, вам лучше делегировать необработанные манипуляции ID3 в существующую библиотеку, такую ​​как id3lib , и сосредоточиться на функциональности вашего редактора.

...