2012-10-18 211 views
2

我敢肯定這個問題被問了很多,但我只是想確保沒有更好的方法來做到這一點。C字符串到寬C字符串

基本上,我有一個const char *指向以空字符結尾的C字符串。我有另一個函數,它期望const wchar_t *指向具有相同字符的字符串。

暫時,我一直在試圖做這樣的:

size_t newsize = strlen(myCString) + 1; 
    wchar_t * wcstring = new wchar_t[newsize]; 
    size_t convertedChars = 0; 

    mbstowcs_s(&convertedChars, wcstring, newsize, myCString, _TRUNCATE); 

    delete[] wcstring; 

我需要在很多地方進行這些轉換,因爲我處理與期待第三方庫的一個或另一個。這是推薦的方式嗎?

+4

它強烈地依賴於'爲const char *'字符串(這可能是UTF-8,ISO-Latin-1的,KOI的假定編碼-8,...)。你必須知道那個編碼。您可能會對http://www.gnu.org/software/libiconv/ library感興趣。 –

+0

你基本上是在正確的軌道上。您可以通過首先運行帶有空指針的'mbstowcs'來獲得正確的目標大小。不要忘記在程序開始時運行'std :: setlocale(「」);''。 –

回答

2

假設你的數據都是ASCII,你所做的幾乎是推薦的做法。如果您有非ASCII數據,您需要知道它的編碼是什麼:UTF-8,Windows-1252,任何ISO 8859變體,SHIFT-JIS等等。每一個都需要以不同的方式轉換。

我只會改變使用mbstowcs而不是mbstowcs_smbstowcs_s只在Windows上可用,而mbstowcs是一個標準的C99功能,它是便攜式的。當然,如果您想避免使用Microsoft編譯器關閉CRT棄用警告而未完全關閉它們,則使用#if測試宏可以在非Windows系統上使用mbstowcs,在Windows系統上使用mbstowcs_s是完全正確的。

您還可以使用mbstowcs獲取轉換字符串的長度,方法是先通過NULL傳遞目標。這樣,無論輸入字符串多長時間,都可以避免截斷;但是,它確實涉及將字符串轉換兩次。

對於非ASCII轉換,我推薦使用libiconv

+1

實際上,它不會從ASCII轉換 - 它會轉換爲當前語言環境中的LC_CTYPE隱含的任何格式,可能是ASCII或UTF-8或其他格式。 –

+0

你可能還想看看mbsrtowcs(3),如果你傳入一個狀態變量,它就是線程安全的。它有一個「更安全」的界面,可在Windows和Linux上使用。 – rholmes

0

你還沒有說過涉及哪些編碼。如果您有非字節字符串,你可以這樣做:

std::string a("hello"); 
std::wstring b(s.begin(), s.end()); 

const wchar_t *wcString= b.c_str();