2012-06-28 40 views
8

我目前正在開發一個適用於Windows和Linux的愛好項目(C/C++),並且完全支持Unicode。可悲的是,Windows和Linux使用不同的編碼,使我們的生活更加困難。C/C++中的跨平臺unicode:使用哪種編碼?

在我的代碼中,我試圖使用盡可能通用的數據,這使得Windows和Linux都很容易。在Windows中,默認情況下,wchar_t編碼爲UTF-16,Linux中編碼爲UCS-4(如果我錯了,請糾正我)。

我的軟件打開({_wfopen,UTF-16,Windows},{fopen,UTF-8,Linux})並將數據寫入UTF-8文件。到目前爲止,這都是可行的。直到我決定使用SQLite。

SQLite的C/C++接口允許使用一個或兩個字節的編碼字符串(click)。 Ofcourse這不適用於Linux中的wchar_t,因爲Linux中的wchar_t默認爲4字節。因此,從sqlite寫入和讀取需要轉換爲Linux。

目前代碼混亂,Windows/Linux的例外情況。我希望能堅持到wchar_t的存儲數據的標準理念:

  • wchar_t的在Windows:文件路徑不會有問題,讀/寫沒有問題的SQLite。無論如何,將數據寫入文件應該使用UTF-8編寫。
  • wchar_t在Linux中:由於UTF-8編碼,在讀取/寫入到sqlite(wchar_t)之前進行轉換以及在將數據寫入文件時與windows相同的文件路徑的例外。

閱讀後(here)我確信我應該堅持在Windows中使用wchar_t。但是,在完成所有這些工作之後,麻煩從移植到Linux開始。

目前我正在考慮重做一切以堅持使用簡單字符(UTF-8),因爲它適用於Windows和Linux,記住我需要'WideCharToMultiByte'Windows中的每個字符串來實現UTF-8。使用簡單的基於char *的字符串將大大減少Linux/Windows的例外數量。

你有任何使用unicode跨平臺的經驗嗎?對使用UTF-8簡單地存儲數據而不是使用wchar_t的想法有什麼想法?

+0

2字節字符編碼絕對是*不* UTF-16。UTF-16是2到4個字節,而UTF-8是1到4個字節。 Windows'wchar_t'不是UTF-16,它是UCS2。在實踐中,您可能沒有注意到這種差異,因爲UCS2涵蓋了BMP,但是如果您的用戶決定他們必須擁有Ogham或符文數據... – user268396

+1

Windows使用UTF-16,並且使用'wchar_t'來保存UTF-16數據,並且自Windows 2000以來一直這樣做。 –

+3

關於wchar_t的用途和用途:http://stackoverflow.com/a/11107667/365496 – bames53

回答

6

UTF-8適用於所有平臺,適用於Windows的即時轉換爲UTF-16是跨平臺Unicode的常用策略。

+0

我會稍微調整一下這個語句,並說:在所有平臺上進行本地編碼,並與UTF-8進行及時轉換。只要字符串離開應用程序(例如寫入文件,通過網絡套接字發送數據,將輸入傳遞到庫等),即時轉換是必需的。當然,這一切都取決於具體的情況。 – IInspectable

2

我們的軟件也是跨平臺的,我們也面臨類似的問題。我們決定,我們的目標是儘可能減少轉換次數。這意味着我們在Windows上使用wchar_t,在Unix/Mac上使用char

我們通過支持_TLPCTSTR在Unix相似,具有通用功能,可以輕鬆地std::stringstd::wstring之間的轉換做到這一點。我們也有一個通用的std::basic_string<TCHAR>tstring),我們在大多數情況下使用。

到目前爲止,這工作得很好。基本上大多數功能需要tstringLPCTSTR,而那些不能從tstring轉換參數的功能。這意味着大多數時候我們不會轉換我們的字符串並通過大多數參數。

+2

這也是一個可能的解決方案,但仍然有點冒失。另外,從我的閱讀中我瞭解到,我應該避免使用TCHAR,因爲它是通過切換到MBCS而不是Unicode標誌來支持向後兼容舊版軟件的。 – ErikKou

+0

@Fozi,如何在Ubuntu Linux上支持_T?非常感謝你。 – Frank

+0

@ErikKou,在Unix或Linux中模擬Windows宏_T的可能解決方案是什麼?謝謝。 – Frank