2009-10-18 6 views
0

Я очень смущен этой маленькой проблемой, которую у меня есть. У меня есть заголовок формата без индексации. (более конкретно заголовок ID3). Теперь этот заголовок хранит строку или, скорее, три байта для конформации, что данные на самом деле являются тегами ID3 (TAG - это строка бит.) Точка, теперь, когда этот TAG в формате файла не равен нулю -завершённый. Таким образом, есть две вещи, которые можно сделать:Формат файла стиля строки стиля C

  • Загрузить весь файл с fread и незавершенных сравнения строк, используют strncmp. Но:
    1. Это звучит Hacky
    2. Что делать, если кто-то открывает его и пытается манипулировать строку без предварительного знания этого?
  • Другой вариант заключается в том, что файл загружается, но структура C не должна точно соответствовать формату файла, но включает в себя правильные нуль-терминаторы, а затем каждый член должен быть загружен с использованием уникального вызова. Но, это тоже чувствует себя взломанным и утомительным.

Помочь, особенно от людей, имеющих практический опыт общения с такими вещами, ценится.

ответ

2

Если спецификация формата файла говорит, что определенные три байта имеют значения, соответствующие «T», «A», «G» (84, 65, 71), тогда вы должны сравнить только эти три байта.

Для этого примера strncmp() в порядке. В общем случае memcmp() лучше, потому что не нужно беспокоиться о завершении строки, поэтому даже если сравниваемый поток байтов (тег) содержит символы ASCII NUL '\ 0', то будет работать memcmp().

Вам также необходимо узнать, является ли формат файла, с которым вы работаете, в первую очередь печатаемые данные или же это в основном двоичные данные. Методы, используемые для печатаемых данных, могут отличаться от методов, используемых для двоичных данных; методы, используемые для двоичных данных, иногда (но не всегда) переводятся для использования с данными для печати. Одно большое различие заключается в том, что длины значений в двоичных данных известны заранее, либо потому, что длина встроена в файл, либо потому, что структура файла известна. Имея печатные данные, вы часто имеете дело с кодировками переменной длины с неявными границами в полях - и перед этим не кодируется информация о кодировке длины.

Например, формат файла пароля Unix представляет собой текстовую кодировку с полями переменной длины; он использует ':' для разделения полей. Вы не можете определить, сколько времени занимает поле, пока вы не встретите следующий «:» или конец строки. Для этого требуется различная обработка из двоичного формата, закодированного с использованием ASN.1 , где поля могут иметь значение индикатора типа (обычно байта) и длину (может быть 1, 2 или 4 байта в зависимости от типа) до фактического данные для поля.


ASN.1 представляет собой (по праву) считается очень сложным; Я привел очень простой пример того, как он используется, и его можно критиковать на многих уровнях. Тем не менее, основная идея действительна - длина (и с ASN.1, обычно тип тоже) предшествует (двоичным) данным. Это также известно как TLV - тип, длина, значение - кодирование.

1

Сохраните три байта и сравните каждый байт с символами 'T', 'A' и 'G'. Это может быть не очень умным, но выполняет работу хорошо и, что более важно, правильно.

+2

И для синтаксического анализа, конкретных, хорошо известных форматов файлов, используйте библиотеку. –

+0

Я говорил о более общем: что, если это была длинная длинная цепочка? – aviraldg

+2

Когда вы пишете парсер формата файла, вы обычно работаете с хорошо известными тегами/метаданными. Кроме того, из того, что я понял, ваш код касается обнаружения и не столько синтаксического анализа. Таким образом, вышеуказанный подход достаточно. В случае, если есть произвольно длинная строка, заголовок, скорее всего, будет иметь поле длины, чтобы вы могли «malloc» так много заранее и считали данные. – dirkgently

2

Если вы что-то изучаете, вы можете найти тег ID3v1 в файле MP3, прочитав последние 128 байт файла и проверив, являются ли первые 3 символа блока TAG.

Для реального применения используйте TagLib.

+0

Вопрос был не в конкретном приложении - это было больше похоже на то, что должно быть подходящим подходом - для любопытных вещей ... – aviraldg

+2

«что должен быть подходящий подход для» всегда зависит от конкретного формата файла. В большинстве форматов вы знаете, где искать идентификаторы, или, по крайней мере, четко определили, как сканировать файл, чтобы найти его. После того, как вы определили блок, для которого вы знаете структуру, вы читаете его по одному полю за раз (и тогда не имеет значения, фиксирован ли он, нуль завершен и т. Д.). Вы никогда не разбираете файлы с C-структурами. –

+2

@ Lukáš Lalinský: «Вы никогда не разбираете файлы с C-структурами». - Это утверждение слишком сильно. Я предлагаю вам взглянуть на zlib. – dirkgently

3

Первое, что нужно учитывать при разборе чего-либо: Длина этих полей либо фиксированная по размеру, либо префиксными подсчетами (которые сами по себе фиксированы по размеру, например, почти каждый графический файл имеет фиксированный размер/структуру заголовок, за которым следуют переменные размеры пикселей)? Или у формата есть поля с полной переменной длины, которые каким-то образом ограничены (например, кадры MPEG4 ограничены байтами 0x00, 0x00, 0x01)? Обычно ответ на этот вопрос будет иметь большое значение, чтобы рассказать вам, как его разобрать.

0

И не забывайте о том, что жанр два разные значения на id3 v1 и ID3v1.1