Unicode下CString與整型之間的轉換

來源:互聯網
上載者:User

MFC中對字串的定義大多是使用CString類,不可避免的有時候需要將CString類型的字串轉換為整形或者其他類型的變數。最近在做的一個項目中就遇到了這樣的問題。

用CString定義了一個由數字組成的字串str,但是需要將其轉換為BYTE型使用。很容易就想到了atoi函數,atoi函數主要功能是將一個字串轉化為整型數,函數原型如下:

[code]int atoi(const char * string ); [/code]

可以看到函數的參數是const char *,經測試在vC 6.0環境下直接轉換是沒有任何問題的。

[code]int n = atoi(str) [/code]

但是同樣的代碼在VS2008環境下會報錯,提示w_char*不能轉為_char*。因為建立工程的時候我勾選了unicode編碼。

原因分析:

在Visual C++ NET環境下,預設的字元集形式是Unicode,但在VC6.0環境下,預設的字元集形式是多位元組字元集(MBCS,Multi-Byte Character Set),這就導致了在VC6.0中非常簡單實用的各類字元操作和函數在VS環境下運行時會出現各種各樣的錯誤。以下給出了VS環境Unicode字元集下CString和char *之間的相互轉換方法,也即Unicode字元集和MBCS字元集的轉換

  1. Unicode下CString轉換為char *
    (1)使用windows API:WideCharToMultiByte進行轉換
    從函數名就可以看出該函數的功能,將unicode編碼的widechar轉換為多位元組字元,查閱msdn,其定義如下:[code]int WideCharToMultiByte(

    UINT CodePage,

    DWORD dwFlags,

    LPCWSTR lpWideCharStr,

    int cchWideChar,

    LPSTR lpMultiByteStr,

    int cbMultiByte,

    LPCSTR lpDefaultChar,

    LPBOOL lpUsedDefaultChar

    );

    [/code]

    第三個參數lpWideCharStr是待轉換的寬字元串,第四個參數cchWideChar表示待轉換字串的長度,第五個參數lpMultiByteStr表示轉換為的多位元組字串指標,第六個參數cbMuliByte表示轉換為的多位元組字串的長度(位元組長度)。函數的傳回值描述如下:Returns the number of bytes written to the buffer pointed to by
    lpMultiByteStr if successful;If the function succeeds and cbMultiByte is 0, the return value is the required size, in bytes, for the buffer indicated by
    lpMultiByteStr. The function returns 0 if it does not succeed. 以下樣本來自網路。

    [code]CString str = _T("("D:\校內項目\QQ.bmp")

    int n = str.GetLength(); // n = 14, n是按字元擷取字串長度,中文字元和英文字元均算作一個字元。

    //擷取多位元組字串長度,按位元組計數,中文字元佔兩位元組

    Int len = WideCharToMultiByte(CP_ACP, 0, str, str.GetLength(), NULL, 0, NULL, NULL) //針對上例len=18,因為中文字元佔2位元組

    //為多位元組字元申請空間,數組大小為按位元組計算的字串長度,注意字串還需要\0結尾

    Char * p = new char[len +1]

    //寬字元串轉換為多位元組編碼的字串

    WideCharToMultiByte(CP_ACP, 0, str, str.GetLength(), p, len, NULL, NULL);

    P[len+1] = '\0'; //<strong>字串以\0結尾 應該是存到p[len]而不是len+1 </strong>[/code]

    (2)使用宏T2A或者W2A
    代碼如下:

    [code]
    CString str = _T("("D:\校內項目\QQ.bmp");

    //宣告身份識別符,這個不能忘記,否則編譯器會報錯

    USES-CONVERSION;

    //調用函數,T2A和W2A均支援ATL和MFC中的字元轉換
    char * p = T2A(str);
    //char * p = W2A(str); //也可實現轉換
    [/code]

    注意: 有時候可能還需要添加引用#include <afxpriv.h> //原文抄過來了,我沒遇到過

  2. unicode下char *轉換為CString
    (1)使用API:MultiByteToWideChar進行轉換

    MultiByteToWideChar用於將多位元組字串轉換為unicode環境下的寬字元。msdn中定義如下:
    [code]
    int MultiByteToWideChar(UINT CodePage,

    DWORD dwFlags,

    LPCSTR lpMultiByteStr,

    int cbMultiByte,

    LPWSTR lpWideCharStr,

    int cchWideChar,

    );
    [/code]

    實現代碼如下:

    [code]
    char * p = "D:\校內項目\QQ.bmp";

    //計算char *數組大小,以位元組為單位,一個漢字佔兩個位元組
    int charLen = strlen(p);

    //計算多位元組字元的大小,按字元計算。
    int len = MultiByteToWideChar(CP_ACP,0,p,charLen,NULL,0);

    //為寬位元組字元數組申請空間,數組大小為按位元組計算的多位元組字元大小
    TCHAR *buf = new TCHAR[len + 1];

    //多位元組編碼轉換成寬位元組編碼
    MultiByteToWideChar(CP_ACP,0,p,charLen,buf,len);

    buf[len] = '\0'; //添加字串結尾,注意不是len+1

    //將TCHAR數群組轉換為CString
    CString pWideChar;
    pWideChar.Append(buf);

    //刪除緩衝區
    delete []buf;
    [/code]

    (2)使用宏A2T或者W2A進行轉換
    代碼如下:

    [code]
    char * pF = "D:\校內項目\QQ.bmp";

    USES_CONVERSION;
    CString s = A2T(p);

    //CString s = A2W(p);
    [/code]

    (3) 使用_T宏,將字串轉換為寬字元

    [code]
    //多位元組字元集,在vc6和vc7種可以編譯通過的語句,但VS2005不能通過,預設為Unicode字元集
    //AfxMessageBox("載入資料失敗",0);

    //書寫代碼使用TEXT("")或_T(""),文本在UNICODE和非UNICODE程式裡都通用
    AfxMessageBox(_T("載入資料失敗"),0);

    //如果是只在Unicode環境下的話,也可以使用L宏

    Str = L"載入資料失敗";
    [/code]

  3. 總結
    直接轉換在基於MBCS的工程中是可以的,但在基於unicode字元集的工程中行不通,CString會以unicode的形式儲存資料,強制轉換隻會返回第一個字元。
  4. 測試代碼:

char m_strIP[256] = "D:\\192.168.1.101";
 int charLen = strlen(m_strIP);
 int len = MultiByteToWideChar(CP_ACP,0,m_strIP,charLen,NULL,0);
 TCHAR *buf = new TCHAR[len + 1];
 MultiByteToWideChar(CP_ACP,0,m_strIP,charLen,buf,len);
 buf[len] = '\0'; //添加字串結尾,注意不是len+1
 CString pWideChar;
 pWideChar.Append(buf);
 delete []buf;//刪除緩衝區

 

 CString CShead(_T("D:\\"));
 CString CStemp(_T("\\"));
  

 char m_strIP[256] = "192.168.1.101";
 USES_CONVERSION;
 CString S1= A2T(m_strIP);
 S1 = CShead + S1;

 CTime t = CTime::GetCurrentTime();

 char dir[10];
 char filename[20];

 memset(dir,0,10);
 memset(filename,0,20);
 sprintf(dir,"%04d%02d%02d", t.GetYear(),t.GetMonth(), t.GetDay());
 int h = t.GetHour();
 int m = t.GetMinute();
 int s = t.GetSecond();
 sprintf(filename,"%02d%02d%02d-%02d%02d%02d.avi",h,m,s,h,m,s+2);
 CString S2= A2T(dir);
 S2 = S1 + CStemp + S2;
 CString FilePath= A2T(filename);
 FilePath = S2 + CStemp + FilePath;
 int err;
 if (!CreateDirectory(S1,NULL))
 {
  if (GetLastError() == ERROR_ALREADY_EXISTS )
  {
   cout<<"ALREADY_EXISTS"<<endl;
  }
  else
   cout<<"error"<<endl;
  
 }

 if (!CreateDirectory(S2,NULL))
 {
  if (GetLastError() == ERROR_ALREADY_EXISTS )
  {
   cout<<"ALREADY_EXISTS"<<endl;
  }
  else
   cout<<"error"<<endl;
 }

 CFile file(FilePath,CFile::modeCreate|CFile::modeReadWrite);
 file.Write(m_strIP,strlen(m_strIP));
 file.Close();

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.