c++中wstring 和 string的轉換


一、wchar_t和char的基礎知識

1.C程序中使用的char類型,是占用一個字節,一共可以表示256個字符。而在32位系統中,char*是占用四個字節的,因為一個指針變量占用的存儲空間為4個字節。char類型的編碼規則一般為ASCII編碼。我在此處測試了一下再GCC中char[]是不可以存儲中文字符的(可能是我的編譯器沒有和編輯器的編碼方式不一樣,導致出來的結果是亂碼的中文),但是在vs中,似乎使用某些優化,char是可以用來存儲中文字符的。但是他們都是顯示出文字來的,ASCII編碼中沒有漢字,但是還是顯示出來了,這本身存在一些我們不知道的操作(這個內容需要自己來深究)。

在嘗試了修改了編碼問題后,GCC編譯器也可以實現中文的輸入了。(待續)

此時,對於這個問題我已經找到了我的答案

普通的char類型是一個正數,是從0-127個編碼,而輸入中文的字符的值第一個字節都是負數(很難受,好像還是不對),可能是通過數字的符號來判定改符號是一個字節還是兩個字節的。因此判定char的編碼規則應該不只是Ascii一種。

 

2.wchar_t在C程序中占用的字節為2個字節,相當於一個無符號短整型。其長度是可變的,根據運行的平台而定,可以是2個字節或者是4個字節。在win32 MSVC環境下,C庫中wchar_t的長度為2個字節

typedefine unsigned short wchar_t;/* 16bits*/

wchar_t采用的是unicode編碼,unicode的編碼是固定的,但是因為其需要2到4個字節,它的存儲方法不盡相同。所以會產生不同版本的unicode。

unicode 的一種實現方式 UTF-8。

參見鏈接https://www.cnblogs.com/kingstarspe/p/ASCII.html

UTF-8的編碼規則很簡單,只有二條:

1)對於單字節的符號,字節的第一位設為0,后面7位為這個符號的unicode碼。因此對於英語字母,UTF-8編碼和ASCII碼是相同的。

2)對於n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。

(未完待續)

wchar_t*與char*的轉換

經過了上面的邏輯討論之后我們可以發現,其實char和wchar_t的轉換過程就是一個編碼轉化的過程,需要大量的判斷語句來實現,其原理大概也就是根據字節的信號來判斷字符需要的字節數。下面僅提高用於編程的模板。

這是在window下的方法,需要添加<windows.h>頭文件

//將單字節char*轉化為寬字節wchar_t*  
wchar_t* AnsiToUnicode( const char* szStr )  
{  
    int nLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, NULL, 0 );  
    if (nLen == 0)  
    {  
        return NULL;  
    }  
    wchar_t* pResult = new wchar_t[nLen];  
    MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, pResult, nLen );  
    return pResult;  
}  
  
//將寬字節wchar_t*轉化為單字節char*  
char* UnicodeToAnsi( const wchar_t* szStr )  
{  
    int nLen = WideCharToMultiByte( CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL );  
    if (nLen == 0)  
    {  
        return NULL;  
    }  
    char* pResult = new char[nLen];  
    WideCharToMultiByte( CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL );  
    return pResult;  
}  

 下面這段代碼實現的是string和wstring的轉換,可能在實際中運用的比較多,(只有在C++中才有string類型哦,純C中只能使用char*或者是char []),稍作修改之后就可以成為char*和wchar_t直接的轉換函數了。該函數用到的頭文件是C中的<string>文件。

//wstring=>string
std::string WString2String(const std::wstring& ws)
{
    std::string strLocale = setlocale(LC_ALL, "");
    const wchar_t* wchSrc = ws.c_str();
    size_t nDestSize = wcstombs(NULL, wchSrc, 0) + 1;
    char *chDest = new char[nDestSize];
    memset(chDest, 0, nDestSize);
    wcstombs(chDest, wchSrc, nDestSize);
    std::string strResult = chDest;
    delete[]chDest;
    setlocale(LC_ALL, strLocale.c_str());
    return strResult;
}
// string => wstring
std::wstring String2WString(const std::string& s)
{
    std::string strLocale = setlocale(LC_ALL, "");
    const char* chSrc = s.c_str();
    size_t nDestSize = mbstowcs(NULL, chSrc, 0) + 1;
    wchar_t* wchDest = new wchar_t[nDestSize];
    wmemset(wchDest, 0, nDestSize);
    mbstowcs(wchDest, chSrc, nDestSize);
    std::wstring wstrResult = wchDest;
    delete[]wchDest;
    setlocale(LC_ALL, strLocale.c_str());
    return wstrResult;
}

(以后不遇見問題,可能就不會再深究了,再見了)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM