2010-07-25 139 views
3
  1. 爲什麼保存爲UTF8(在Notepad ++中)的文件在fstream的開頭有這個字符我在C++程序中打開它?C++ ifstream UTF8第一個字符

    '╗┐

    我不知道它是什麼,我只知道,它不存在,當我保存到ASCII。 更新:如果我將它保存到UTF8(沒有BOM),它不在那裏。

  2. 如何在C++中檢查文件的編碼(ASCII或UTF8,其他所有內容將被拒絕;))。這正是這些人物嗎?

謝謝!

+0

你可以給我們一個十六進制轉儲的文件的開頭,而不是我們不認識的幾個隨機字符(並且我們的字體可能不會顯示?) – 2010-07-25 15:53:14

+1

它可能是一個UTF-8 BOM誤解作爲IBM850。 – dan04 2010-07-26 04:39:43

回答

7

當您將文件另存爲UTF-16時,每個值都是兩個字節。不同的電腦使用不同的字節順序一些首先放置最重要的字節,一些首先放置最不重要的字節。 Unicode保留一個稱爲字節順序標記(BOM)的特殊碼點(U + FEFF)。當一個程序用UTF-16編寫一個文件時,它將這個特殊的代碼點放在文件的開頭。當另一個程序讀取一個UTF-16文件時,它知道應該有一個BOM。通過將實際字節與預期BOM進行比較,可以判斷讀者是否使用與寫入器相同的字節順序,或者是否必須交換所有字節。

保存UTF-8文件時,字節順序沒有歧義。但是一些程序,尤其是爲Windows編寫的程序仍然添加一個BOM,編碼爲UTF-8。將BOM代碼點編碼爲UTF-8時,會得到三個字節,0xEF 0xBB 0xBF。這些字節對應於大多數OEM代碼頁中的框圖字符(這是Windows上的控制檯窗口的默認字符)。

贊成這樣做的理由是它將文件標記爲真正的UTF-8,而不是其他本地編碼。例如,西方Windows上的許多文本文件都在代碼頁1252中。使用UTF-8編碼的BOM標記文件可以更容易地區分差異。

反對這樣做的觀點是很多程序期望ASCII或UTF-8無論如何,也不知道如何處理額外的三個字節。

如果我正在編寫一個讀取UTF-8的程序,我會在開始時檢查這三個字節。如果他們在那裏,跳過他們。

更新:您可以將U+FEFF ZERO WIDTH NO BREAK字符轉換爲U+2060 WORD JOINER [吉勒姆,理查德,統一揭祕除了在文件的開頭,Addison-Wesley出版社,2003,頁。 108]。我的個人代碼這樣做。如果在解碼UTF-8時,我在文件開頭看到0xEF 0xBB 0xBF,我認爲它確實是UTF-8。如果文件不是以這些字節開頭的,我只是正常解碼。如果在文件稍後解碼時遇到U + FEFF,則發出U + 2060並繼續。這意味着U + FEFF僅用作BOM,而不是其不推薦的含義。

+1

「反對這樣做的觀點是很多程序都希望使用ASCII或UTF-8,並且不知道如何處理額外的三個字節。」我沒有關注。 'EF BB BF'是UTF-8,代表一個零寬度,非破壞性的空間 - 基本上意味着「沒有」,這就是選擇BOM的原因。如果一個程序讀取UTF-8,它必須能夠讀取這個字符並知道如何處理它。 – sbi 2010-07-25 16:08:00

+0

它比這強得多。不允許在UTF編碼文件中省略BOM。由於顯而易見的原因,讀取該文件的程序將不能猜測它包含UTF編碼文本。 – 2010-07-25 16:16:22

+1

@Hans:TTBOMK,BOM始終是可選的,從不需要。 – sbi 2010-07-25 16:29:14

1

爲什麼保存爲UTF8 文件必須在開始這個人物[...]我不知道它是什麼,我只知道,它不存在,當我保存到ASCII。

我想你指的是字節順序標記(BOM)U+FEFF,一個零寬度,不間斷的空格字符。這裏(記事本++ 5.4.3)保存爲UTF-8的文件在開頭處具有字符EF BB BF。我想這就是用UTF-8編碼的物料清單。

我如何檢查文件

你不能的編碼。你必須知道什麼編碼你的文件被寫入。雖然Unicde編碼文件可能開始與物料清單,我不認爲有要求,他們這樣做。

0

我猜你的意思是問,爲什麼它有這些字符。這些字符可能是byte order mark,根據UTF-8中的鏈接,字節EF BB BF。

至於知道什麼編碼文件是在,你不能從文件本身得到。你必須提前知道它(或詢問誰提供你的文件)。爲了更好地理解編碼而不必進行大量閱讀,我強烈建議Joel Spolsky的The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

+1

引用維基百科作爲參考是一種不好的做法,你應該打破http://en.wikipedia.org/wiki/Wikipedia:Citing_Wikipedia。維基百科是開始研究和尋找權威參考的好點,但它絕不應該被用作參考,因爲它具有無法驗證的作者身份,也不知道作者無法知道他們評論的質量或準確性。該wiki文章中提到了一個更好的參考資料,指向官方的Unicode網站:http://www.unicode.org/faq/utf_bom.html – 2010-07-25 16:50:03

+0

一個很好的觀點。我已經相應地修改了我的答案。 – SCFrench 2010-07-25 18:10:43

0

不知道這些字符真正是什麼(即沒有十六進制轉儲),這只是一個猜測,但我的直接猜測是,你看到的是一個字節順序標記(BOM)和( )編碼爲UTF-8。從技術上講,你不能/應該這樣做,但在實踐中,它實際上是相當普遍的。

只是爲了澄清,你應該認識到,這個不是真的是一個字節順序標記。字節順序標記的基本概念不適用於UTF-8。理論上,UTF-8編碼絕不應該應用於物料清單 - 但您可以忽略它,並將正常的UTF-8編碼規則應用於構成物料清單的值(如果需要)。

+1

有點強烈的說」UTF-8編碼永遠不應該應用於BOM 」。將它用於字節排序是多餘的,但它作爲編碼簽名是可以允許的。請參閱http://unicode.org/faq/utf_bom.html#bom5 – 2010-07-25 19:48:44

1

關於第二點,每個有效的ASCII字符串也是有效的UTF-8字符串,因此您不必顯式檢查ASCII。只需使用UTF-8讀取文件,如果文件不包含有效的UTF-8字符串,則會出現錯誤。