2017-05-11 51 views
3

我想讀這可能有任何字符集/代碼頁文件,但我沒有哪個區域,以便正確讀取該文件來設置。檢測文件的字符集動態地在C++中

以下是我的代碼段,其中我試圖讀取一個charset爲windows-1256的文件,但我想從正在讀取的文件中動態獲取字符集,以便相應地設置語言環境。

std::wifstream input{ filename.c_str() }; 
std::wstring content{ std::istreambuf_iterator<wchar_t>(input1), std::istreambuf_iterator<wchar_t>() }; 
input.imbue(std::locale(".1256")); 
contents = ws2s(content); // Convert wstring to CString 

回答

2

一般來說,這是不可能的,只能準確地使用純文本文件的內容。通常你應該依靠一些外部信息。例如,如果文件是使用HTTP下載的,則應在響應頭中接收編碼。

某些文件可能包含有關由文件格式指定的編碼的信息。 XML例如:<?xml version="1.0" encoding="XXX"?>。這是可選的 - 如果文件用字節順序標記開始

Unicode編碼可以被檢測到。

通常可以認爲,編碼採用的是寬字符,如果該文件包含零字節 - 這將是一個字符串結束的窄字符 - 文件結束前。同樣,如果您發現兩個連續的零對齊到一個2字節的邊界(結束之前),那麼編碼可能是4個字節寬。

除此之外,你可以嘗試猜測基於某些字符的頻率編碼。這可以有一些unintended consequences

+0

目前還沒有確定字符集的完全證明方式,但我們可以使用ICU庫來提供基於啓發式的解決方案。我使用了https://github.com/mooz/node-icu-charset-detector/blob/master/node-icu-charset-detector.cpp –

+0

@SaurabhKathpalia是的一個片段,外包給圖書館是一種很好的方式節省時間和精力。只要記住啓發式方法的潛在缺陷(我的答案的最後一個環節就是這種陷阱的一個實際例子)。 – user2079303

1

讓我坦率地說,並說:你不能

讓我有資格說:一個文件只是噸的0和1的粘到磁盤上。字符集是解釋這些0和1的方法。 必須提供有關如何解釋它們的信息,即通過指定字符集。

這樣做的典型方式是通過寫一個標題來指定字符集。

這是一個html頭

<head> 
    <title>Page Title</title> 
    <meta charset="UTF-8"> 
</head> 

正如你所看到的,字符集必須指定這種或那種方式。

有一段時間,你會發現一些流氓應用程序猜測字符集,他們經常這樣做,用字節分佈的一些啓發式方法,但這不是可靠的,往往會導致亂碼。

作爲一個側面說明,儘量使用UTF-8 everywhere,其他都是,把它輕輕地,凌亂。