2009-10-18 56 views
0

我很困惑這個小問題,我有。我有一個非索引文件格式標題。 (更具體地說是ID3頭部)現在,這個頭部存儲一個字符串或三個字節的數據實際上是一個ID3標籤(TAG是字符串btw。),現在這個TAG在文件格式不是空封端的。因此,有可以做兩件事情:一個C風格的字符串文件格式難題

  • 負載與fread和未終止字符串比較整個文件,使用strncmp。但是:
    1. 這聽起來很哈克
    2. 如果什麼有人打開它,並試圖操縱字符串W/O的這個先驗知識?
  • 另一個選擇是文件被加載,但C結構不應該精確地映射到文件格式,但包含適當的null結束符,然後每個成員應該使用唯一調用進行加載。但是,這也令人感到不安和乏味。

幫助,尤其是來自具有處理這些東西的實際經驗的人的幫助,表示讚賞。

回答

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

而且,用於解析,具體的,知名的文件格式,使用圖書館。 – 2009-10-18 14:31:10

+0

我在談論一個更普遍的東西 - 如果它是一個任意長度的字符串呢? – aviraldg 2009-10-18 14:31:51

+2

當您編寫文件格式解析器時,通常使用熟知的標籤/元數據。此外,從我的理解,你的代碼是關於檢測,而不是解析。所以,上述方法就足夠了。如果有一個任意長的字符串,頭文件最有可能有一個「長度」字段,這樣你可以事先'malloc'並且讀取數據。 – dirkgently 2009-10-18 14:35:30

2

如果您只是在學習一些東西,您可以通過讀取文件的最後128個字節,並檢查該塊的前3個字符是否爲TAG,在MP3文件中找到ID3v1標籤。

對於實際應用,請使用TagLib

+0

這個問題不是關於一個特定的應用程序 - 它更像是什麼 - 應該是適當的方法 - 對於那種事情... – aviraldg 2009-10-18 14:48:50

+2

「什麼應該是適當的方法 - 」總是取決於具體的文件格式。在大多數格式中,您知道在哪裏查找標識符,或者至少有明確定義的方式來掃描文件以找到標識符。一旦確定了知道結構的程序塊,就一次讀取一個字段(然後無論它是否爲固定大小,空值終止等都無關緊要)。你永遠不會用C結構解析文件。 – 2009-10-18 14:53:13

+2

@LukášLalinský:「你永遠不會用C結構解析文件。」 - 這個說法有點過於強烈。我建議你看看zlib。 – dirkgently 2009-10-18 15:00:28

3

解析任何東西時首先要考慮的是:這些字段的長度是固定大小還是以計數爲前綴(它們本身的大小是固定的,例如幾乎每個圖形文件都有固定的大小/結構頭後跟一個可變大小的像素序列)?或者,格式是否具有完全可變長度的字段(例如,MPEG4幀由字節0x00,0x00,0x01定界)?通常這個問題的答案將會告訴你如何解析它。

0

而且不要忘了流派的ID3 v1的兩個不同的含義和ID3V1.1