簡體   English   中英

C ++ ifstream UTF8的第一個字符

[英]C++ ifstream UTF8 first characters

  1. 為什么保存為UTF8的文件(在Notepad ++中)在我在c ++程序中打開它的fstream開頭有這個字符?

    '╗┐

    我不知道它是什么,我只知道當我保存到ASCII時它不存在。 更新:如果我將它保存為UTF8(沒有BOM),它就不存在了。

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

謝謝!

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

保存UTF-8文件時,字節順序沒有歧義。 但有些程序,特別是為Windows編寫的程序,仍然會添加一個編碼為UTF-8的BOM。 將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但文件開頭除外[Gillam,Richard, Unicode Demystified ,Addison-Wesley,2003,p。 108]。 我的個人代碼是這樣做的。 如果,在解碼UTF-8時,我在文件的開頭看到0xEF 0xBB 0xBF,我認為這是一個幸福的信號,我確實有UTF-8。 如果文件不以這些字節開頭,我只是正常進行解碼。 如果,在文件中稍后解碼時,我遇到U + FEFF,我發出U + 2060並繼續。 這意味着U + FEFF僅用作BOM而不是其棄用含義。

為什么保存為UTF8的文件在開頭沒有這個字符[...]我不知道它是什么,我只知道當我保存到ASCII時它不存在。

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

如何檢查文件的編碼

你不能。 您必須知道您的文件編碼的編碼方式。雖然Unicde編碼的文件可能以BOM開頭,但我認為並不要求他們這樣做。

在不知道這些字符究竟是什么的情況下(即沒有十六進制轉儲),這只是猜測,但我的直接猜測是你所看到的是采用字節順序標記(BOM)和(某種)編碼的結果它作為UTF-8。 從技術上講,你不允許/應該這樣做,但在實踐中它實際上相當普遍。

只是為了澄清,你應該意識到這不是一個字節順序標記。 字節順序標記的基本思想不適用於UTF-8。 從理論上講,UTF-8編碼永遠不應該應用於BOM - 但您可以忽略它,並且如果您願意,可以將正常的UTF-8編碼規則應用於構成BOM的值。

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

我猜你想問,為什么它有這些角色。 這些字符可能是字節順序標記 ,根據UTF-8中的鏈接,字節為EF BB BF。

至於知道文件的編碼是什么,你不能從文件本身派生出來。 您必須提前知道(或詢問向您提供文件的用戶)。 為了更好地理解編碼而不必大量閱讀,我強烈推薦Joel Spolsky的絕對最低每個軟件開發人員,絕對必須知道Unicode和字符集(沒有借口!)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM