Считать определённое количество данных по определённому смещению. Разбор ID3v2 mp3 тегов - C (СИ)
Формулировка задачи:
Работаю с mp3 тегами. Задача - считать определённое количество данных по определённому смещению.
Если при считывании тегов версии ID3v1 проблем не возникает, так как данные идут друг за другом и имеют фиксированный размер,то в версии V2 всё иначе.
Теги имеют различную длину и как-то хитро записаны в mp3 файл.
Во втором случае теги начинаются с определённого фрейма (в моём случае COMM) (4 байта). Потом идёт размер в байтах (выделено 4 байта). Потом ещё какая-то информация //Кто знает..подскажите. И потом собственно само описание фрейма. Если посмотреть на скриншот то информация записана в немного изменённом виде. Буквы чередуются с 0x00 байтами.
Считываю я это всё так
Где собственно length и есть длина строки с описанием.
В hex вывожу так
Мне нужно удалить 0x00 байты из данной последовательности.
Понятное дело..можно сделать и так
но мне нужно это дело провернуть в HEX.
а с HEX я не очень.
второй вопрос
fread(&name,length,1,file);
static void hex_print(const void* pv, size_t len) { const unsigned char * p = (const unsigned char*)pv; if (NULL == pv) printf("NULL"); else { size_t i = 0; for (; i<len;++i){ printf("%02X ", *p++);} printf("%s",*p); printf("\n"); }
for(int i=0;i<sizeof(name)-1;i++){ if (name[i]==0){ for (int j=i;j<sizeof(name)-1;j++){ name[j]=name[j+1]; name[j+1]=0; } } }
Прошу пример кода,где можно удалить из строки определённые байты.
как мне из последовательности байт..допустим 00 00 00 44. Получить значение типа Int?
Решение задачи: «Считать определённое количество данных по определённому смещению. Разбор ID3v2 mp3 тегов»
textual
Листинг программы
#include <stdio.h> #include <netinet/in.h> // нужна для ntohl() под Windows заменить на WinSock2.h int main() { unsigned char buff[] = { 0x43,0x4F,0x4D,0x4D, // COMM 0x00,0x00,0x00,0x1D, // block length 0x00,0x00, // \0\0 0x03,0x65,0x6E,0x67,0x00, // \x03eng\0 0x28,0x45,0x64,0x69,0x74,0x29,0x20,0x5B, 0x32,0x30,0x31,0x31,0x20,0x2D,0x20,0x52, 0x65,0x6D,0x61,0x73,0x74,0x65,0x72,0x5D, 0x00 }; char * p = (char*) buff; printf("chunk = '%s'\n", p); p += 4; printf("block length = %d\n", ntohl(*((uint32_t*)p))); p += 4 + 2; printf("subblock length = %d\n", *p); printf("lang = '%s'\n", &p[1]); p += *p + 1 + 1; printf("comment = '%s'\n", p); return 0; }
Объяснение кода листинга программы
- Включаем необходимые заголовочные файлы:
include
include <netinet/in.h>
- Объявляем основную функцию программы: int main()
- Создаём массив данных: unsigned char buff[] = { 0x43,0x4F,0x4D,0x4D, // COMM 0x00,0x00,0x00,0x1D, // block length 0x00,0x00, 0x03,0x65,0x6E,0x67,0x00, // \x03eng\0 0x28,0x45,0x64,0x69,0x74,0x29,0x20,0x5B, 0x32,0x30,0x31,0x31,0x20,0x2D,0x20,0x52, 0x65,0x6D,0x61,0x73,0x74,0x65,0x72,0x5D, 0x00 };
- Объявляем указатель на начало массива: char p = (char) buff;
- Выводим значение первого поля:
printf(
chunk = '%s'\n
, p); p += 4; - Выводим значение второго поля:
printf(
block length = %d\n
, ntohl(((uint32_t)p))); p += 4 + 2; - Выводим значение третьего поля:
printf(
subblock length = %d\n
, *p); - Выводим значение четвёртого поля:
printf(
lang = '%s'\n
, &p[1]); p += *p + 1 + 1; - Выводим значение пятого поля:
printf(
comment = '%s'\n
, p); - Завершаем работу программы: return 0;