這兩天浪費了一點時間在編碼轉換上。我們使用到的一個算法庫,接口參數是一個wchar_t*,作爲文件路徑。經過實驗,幾種方法都沒有用,是個麻煩問題。記錄一下。找到了下面三種可以工作的方式。
方法1:
file = filename.toStdWString();
const wchar_t* str1 = file.c_str();
Returns a std::wstring object with the data contained in this QString. The std::wstring is encoded in utf16 on platforms where wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms where wchar_t is 4 bytes wide (most Unix systems).
這是最樸素的想法。也是最好使用的辦法。很奇怪的是,我前幾次測試,卻是debug看到了亂碼,我也不確定是否是改動了其他宏或者build參數導致的。不過,後來的測試表明,這種方式纔是正確的方式,可能存在的問題最小。
方法2:
wchar_t str2[256] = {0};
auto xxx = filename.toWCharArray(str2);
這種方法是查詢QString 文檔而知的。但是,這種方式要謹慎,若不對數組str2 初始化,debug可以看到字符串最後會多出來一兩個字符,完全隨機的。還要注意數組長度。
方法3:
const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(filename.utf16());
雖然這種方法也能工作,但是需要注意。這裏用到了強轉,reinterpret_cast 表達式不會編譯成任何 CPU 指令,它純粹是一個編譯時指令,指示編譯器將 表達式 視爲如同具有 新類型 類型一樣處理。亦即,與C寫法,(const wchar_t *)ptr 並沒有什麼不同。
其實,最重要的,我們還是需要知道 OS 使用的編碼方式。
C:\Users\kt>chcp
活動代碼頁: 936
這就是 GB2312 了。每個漢字及符號以兩個字節來表示。
Fills the array with the data contained in this QString object. The array is encoded in utf16 on platforms where wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms where wchar_t is 4 bytes wide (most Unix systems).
所以,方法3,只能在windows上使用,在Linux上,還需要注意。
至於從wchar_t* 轉換爲QString的方式,直接參看QString的接口,上述1、3方法對應的接口有fromStdWString、fromUtf16,應該可以解決問題。