Unicode下CString(wchar_t)轉換爲 char*

wstring MultCHarToWideChar(string str)
{
    //獲取緩衝區的大小,並申請空間,緩衝區大小是按字符計算的
    int len=MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),NULL,0);
    TCHAR *buffer=new TCHAR[len+1];
    //多字節編碼轉換成寬字節編碼
    MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),buffer,len);
    buffer[len]='/0';//添加字符串結尾
    //刪除緩衝區並返回值
    wstring return_value;
    return_value.append(buffer);
    delete []buffer;
    return return_value;
}
string WideCharToMultiChar(wstring str)
{
    string return_value;
    //獲取緩衝區的大小,並申請空間,緩衝區大小是按字節計算的
    int len=WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),NULL,0,NULL,NULL);
    char *buffer=new char[len+1];
    WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),buffer,len,NULL,NULL);
    buffer[len]='/0';
    //刪除緩衝區並返回值
    return_value.append(buffer);
    delete []buffer;
    return return_value;
}

於是使用
string mstring = WideCharToMultiChar( (LPCTSTR)mCString );
strcpy_s( pach, sizeof(pach), mstring.c_str() );

 

 

 

 

 

 

void ConvertUnicodeToAscii(const CString &csFilestr, char* pszData)
{
   
int iFileLength = csFilestr.GetLength();
   
char * szBuff;
    szBuff
= new char[iFileLength*sizeof(TCHAR)+sizeof(TCHAR)];

#if !defined (_WIN32_WCE) && !defined(_UNICODE)
    strcpy(szBuff,(LPCTSTR)csFilestr);
#else
    iFileLength
= WideCharToMultiByte(CP_OEMCP,
        WC_COMPOSITECHECK,
        csFilestr,
        iFileLength,
        szBuff,
        iFileLength
*sizeof(TCHAR)+sizeof(TCHAR),
        NULL,NULL);
#endif
    szBuff[iFileLength]
= '/0';
    strcpy(pszData, szBuff);

    delete[] szBuff;
    szBuff
= NULL;
}
★在UNICODE下,同樣的CString str= "str"會報錯誤的!!!

應該是:CString str = L"str";
或者 CString str = _T("str");

★ANSI中CString 裏面的串類型相當於 char *
UNICODE裏面的卻相當於: WCHAR *

★UNICODE下的CString 事實上是CStringW
ANSI下的CString 事實上是CStringA,只不過使用宏CString隱藏了

CString 是一種很特殊的 C++ 對象,它裏面包含了三個值:一個指向某個數據緩衝區的指針、一個是該緩衝中有效的字符記數(它是不可存取的,是位於
CString 地址之下的一個隱藏區域)以及一個緩衝區長度。
有效字符數的大小可以是從0到該緩衝最大長度值減1之間的任何數(因爲字符串結尾有一個NULL字符)。字符記數和緩衝區長度被巧妙隱藏。

 

 

 

CString ,BSTR ,LPCTSTR之間關係和區別

CString是一個動態TCHAR數組,BSTR是一種專有格式的字符串(需要用系統提供的函數來操縱,LPCTSTR只是一個常量的TCHAR指針。

                              CString 是一個完全獨立的類,動態的TCHAR數組,封裝了 + 等操作符和字符串操作方法。
                              typedef OLECHAR FAR* BSTR;
                              typedef const char * LPCTSTR;

                              vc++中各種字符串的表示法
                              首先char*
                              是指向ANSI字符數組的指針,其中每個字符佔據8位(有效數據是除掉最高位的其他7位),這裏保持了與傳統的C,C++的兼容。
                              LP的含義是長指針(long
                              pointer)。LPSTR是一個指向以‘/0’結尾的ANSI字符數組的指針,與char*可以互換使用,在win32中較多地使用LPSTR。
                              而LPCSTR中增加的‘C’的含義是“CONSTANT”(常量),表明這種數據類型的實例不能被使用它的API函數改變,除此之外,它與LPSTR是等同的。
                              1.LP表示長指針,在win16下有長指針(LP)和短指針(P)的區別,而在win32下是沒有區別的,都是32位.所以這裏的LP和P是等價的.
                              2.C表示const
                              3.T是什麼東西呢,我們知道TCHAR在採用Unicode方式編譯時是wchar_t,在普通時編譯成char.
                              爲了滿足程序代碼國際化的需要,業界推出了Unicode標準,它提供了一種簡單和一致的表達字符串的方法,所有字符中的字節都是16位的值,其數量也可以滿足差不多世界上所有書面語言字符的編碼需求,開發程序時使用Unicode(類型爲wchar_t)是一種被鼓勵的做法。
                              LPWSTR與LPCWSTR由此產生,它們的含義類似於LPSTR與LPCSTR,只是字符數據是16位的wchar_t而不是char。
                              然後爲了實現兩種編碼的通用,提出了TCHAR的定義:
                              如果定義_UNICODE,聲明如下:
                              typedef wchar_t TCHAR;
                              如果沒有定義_UNICODE,則聲明如下:
                              typedef char TCHAR;
                              LPTSTR和LPCTSTR中的含義就是每個字符是這樣的TCHAR。
                              CString類中的字符就是被聲明爲TCHAR類型的,它提供了一個封裝好的類供用戶方便地使用。
                              LPCTSTR:
                                   #ifdef _UNICODE
                                      typedef const wchar_t * LPCTSTR;
                                   #else
                                      typedef const char * LPCTSTR;
                                   #endif
                              VC常用數據類型使用轉換詳解

 

 

 

 

單寬字節互換的程序,估計以後還用得着。
void MyWideCharToMultiByte(WCHAR* wchars,CHAR* schars,int scharsLen)
  {
        memset(schars,0,scharsLen);
        CString m_snd = wchars;
        int len = m_snd.GetLength();
        CString tmpstr(m_snd); //複製要發送的字符串
        int multibytelen=WideCharToMultiByte( //計算從Unicode轉換到Ansi後需要的字節數
        CP_ACP, //根據ANSI code page轉換
        WC_COMPOSITECHECK | WC_DEFAULTCHAR, //轉換出錯用缺省字符代替
        (LPCWSTR)tmpstr.GetBuffer(len), //要轉換的字符串地址
                len, //要轉換的個數
                0, //轉換後字符串放置的地址
                0, //最多轉換字符的個數,爲0表示返回轉換Unicode後需要多少個字節
                0, //缺省的字符:"/0"
                0 //缺省的設置
         );
        WideCharToMultiByte( //轉換Unicode到Ansi
                CP_ACP,
                WC_COMPOSITECHECK | WC_DEFAULTCHAR,
                (LPCWSTR)tmpstr.GetBuffer(len),
                len,
                (char *)schars, //轉換到緩衝區中
                scharsLen, //最多個字節
                0,
                0
          );
  }
//程序接收到的字符串最後保存到CString tmpstr中.
  //接收函數片斷
  void MyMultiByteToWideChar(char* schars,CString &wstr)
  {
        // TODO: Add your specialized code here and/or call the base class
//      char * p = "abcdefg我是誰hijk";
        int widecharlen=MultiByteToWideChar( //計算從Ansi轉換到Unicode後需要的字節數
                CP_ACP,
                MB_COMPOSITE,
                (char*)schars, //要轉換的Ansi字符串
                -1, //自動計算長度
                0,
                0
        );
        CString tmpstr;
        tmpstr.GetBuffer(widecharlen); //爲轉換後保存Unicode字符串分配內存
        MultiByteToWideChar( //從Ansi轉換到Unicode字符
                CP_ACP,
                MB_COMPOSITE,
                (char*)schars,
                -1,
                (LPWSTR)tmpstr.GetBuffer(widecharlen), //轉換到tmpstr
                widecharlen //最多轉換widecharlen個Unicode字符
        );
        wstr = tmpstr;
  }

void TestFunction()
{
    TCHAR abc[]=_T("ab我們的家ab");
    char b[15];
    MyWideCharToMultiByte(abc,b,sizeof(b));
   
//    char c[]="ab如果cd就好了!abcdefg";
    CString str;
    MyMultiByteToWideChar(b,str);

    MyWideCharToMultiByte((LPWSTR)str.GetBuffer(0),b,sizeof(b));
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章