Jazyk C 2013 – 6. cvičenie [ID3 tagy]

Z neznámej MP3 zistite a autora, názov skladby.

  • Využime ID3 tag.
    • 128bajtov od konca súboru je TAG
    • začína TAG
    • názov skladby je od bajtu s indexom 3 a má 30 znakov
    • názov umelca je od bajtu s indexom 33 a má 30 znakov

Využité funkcie:

  • fseek() posúva kurzor na danú pozíciu
  • relatívna pozícia od konca súboru: záporné čísla a využitie konštanty SEEK_END
  • tag načítajme do (128 + 1)-znakového buffera cez fgets()
  • korektnosť tagu overme zistením, či prvé tri znaky buffera sú 'T', 'A', 'G'.
  • podreťazce získame kopírovaním cez strncpy do pomocného buffera dĺžky 30 + 1.
    • pozor na to, že strncpy neukončuje automaticky kopírovaný reťazec null-znakom.
  • využime pointerovú aritmetiku: pre reťazec tag vieme získať podreťazec od n-tej pozície cez tag + n
    • pozor, nejde o sčítavanie poľa a čísla
    • ani o sčítavanie poľa a reťazca
    • pole je ekvivalentné pointeru na prvý prvok a pointer je adresa, ku ktorej môžeme môžeme pripočítavať celé čísla
    • a tým sa odkazovať na nasledujúce prvky
  • na vymazanie buffera použime memset.
    • zapisujeme znaky 0
    • veľkosť poľa s korektnými dátovými typmi: sizeof(char) * dlzka

Zdroje

Celý zdroják

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

#define DLZKA_TAGU 128

#define TITUL_OFFSET 3
#define AUTOR_OFFSET 30 + TITUL_OFFSET

int main() {
        char tag[DLZKA_TAGU + 1];

        char buf[30 + 1];

        FILE * subor = fopen("/tmp/file.mp3", "rb");
        if(subor == NULL) {
                perror("Subor sa neda otvorit");
                return -1;
        }
        fseek(subor, -128, SEEK_END);

        fgets(tag, 128 + 1, subor);

        if(tag[0] != 'T' || tag[1] != 'A' || tag[2] != 'G') {
                perror("Chyba ID3v1 tag");
                return -2;
        }

        strncpy(buf, tag + TITUL_OFFSET, 30);

        printf("Nazov skladby je: %s\n", buf);

        strncpy(buf, tag + AUTOR_OFFSET, 30);
        printf("Autor je: %s\n", buf);

        memset(buf, '\0', sizeof(char) * 31);

        strncpy(buf, tag + 93, 4);
        buf[4] = '\0';
        printf("Rok je: %s\n", buf);

        printf("Zaner je: %d", tag[127]);

        fclose(subor);

        return 0;
}

Celý zdroják [vrátane rozumných offsetov]

Namiesto porovnávania hlavičky sa použije porovnanie podreťazca strstr():

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

#define DLZKA_TAGU 128
#define DLZKA_BUFFERA 30

#define TITUL_OFFSET 3
#define TITUL_DLZKA 30

#define AUTOR_OFFSET (TITUL_OFFSET + TITUL_DLZKA)
#define AUTOR_DLZKA 30

#define ROK_OFFSET 93
#define ROK_DLZKA 4

#define ZANER_OFFSET 127

int main() {
        char tag[DLZKA_TAGU + 1];

        char buf[DLZKA_BUFFERA + 1];

        FILE * subor = fopen("/tmp/file.mp3", "rb");
        if(subor == NULL) {
                perror("Subor sa neda otvorit");
                return -1;
        }
        fseek(subor, -DLZKA_TAGU, SEEK_END);

        fgets(tag, DLZKA_TAGU + 1, subor);

        if(strstr(tag, "TAG")) {
                perror("Chyba ID3v1 tag");
                return -2;
        }

        strncpy(buf, tag + TITUL_OFFSET, TITUL_DLZKA);

        printf("Nazov skladby je: %s\n", buf);

        strncpy(buf, tag + AUTOR_OFFSET, AUTOR_DLZKA);
        printf("Autor je: %s\n", buf);

        memset(buf, '\0', sizeof(char) * (DLZKA_BUFFERA + 1));

        strncpy(buf, tag + ROK_OFFSET, ROK_DLZKA);
        buf[ROK_DLZKA] = '\0';
        printf("Rok je: %s\n", buf);

        printf("Zaner je: %d", tag[ZANER_OFFSET]);

        fclose(subor);

        return 0;
}

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *