1. 程式人生 > >ANSI與Unicode之間的編碼轉換

ANSI與Unicode之間的編碼轉換

1.標頭檔案中要定義巨集;   
      #define   UNICODE   
      #define   _UNICODE   
  ////////////////////

char   buf[128];   
  memset(buf,0,128);   
  strcpy(buf,"你好");   
  WCHAR   pCName[128];   
  memset(pCName,0,128);   
  MultiByteToWideChar(CP_THREAD_ACP,MB_USEGLYPHCHARS,buf,strlen(buf),pCName,128);   
   至於WCHAR   轉換到CHAR,則用   
  WideCharToMultiByte

//////////////////////////


  2.char轉換成wchar
   
      const   char   *pFilePathName   =   "c://aa.dll";   
      int   nLen   =   strlen(pFilePathName)   +   1;   
      int   nwLen   =   MultiByteToWideChar(CP_ACP,   0,   pFilePathName,   
nLen,   NULL,   0);   
    
      TCHAR   lpszFile[256];   
      MultiByteToWideChar(CP_ACP,   0,   pFilePathName,   nLen,   lpszFile,   
nwLen);   
    
  3.wchar轉換成char

   
        char   *pFilePathName;   
        TCHAR   lpszFile[256];   
      _tcscpy(lpszFile,   _T("c://aa.dll"));   
    
      int   nLen   =   wcslen(wstr)+1;     
      WideCharToMultiByte(CP_ACP,   0,   lpszFile,   nLen,   pFilePathName,   
2*nLen,   NULL,   NULL);
  

char*和CString轉換 
CString 是一種很特殊的 C++ 物件,它裡面包含了三個值:一個指向某個資料緩衝區的指標、一個是該緩衝中有效的字元記數(它是不可存取的,是位於 
CString 地址之下的一個隱藏區域)以及一個緩衝區長度。 
有效字元數的大小可以是從0到該緩衝最大長度值減1之間的任何數(因為字串結尾有一個NULL字元)。字元記數和緩衝區長度被巧妙隱藏。

(1) char*轉換成CString
  若將char*轉換成CString,除了直接賦值外,還可使用CString::Format進行。例如:
         char chArray[] = "Char  test";
         TCHAR * p = _T("Char  test");( 或LPTSTR p = _T("Char  test");)
         CString theString = chArray;
         theString.Format(_T("%s"), chArray);
         theString = p;

(2) CString轉換成char*

  若將CString類轉換成char*(LPSTR)型別,常常使用下列三種方法:

  方法一,使用強制轉換。例如:

       CString theString( (_T("Char test "));
        LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;

  方法二,使用strcpy。例如:

       CString theString( (_T("Char test "));
       LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
        _tcscpy(lpsz, theString);

  需要說明的是,strcpy(或可移值的_tcscpy)的第二個引數是 const wchar_t* (Unicode)或const char* 
(ANSI),系統編譯器將會自動對其進行轉換。

  方法三,使用CString::GetBuffer。
        如果你需要修改 CString 中的內容,它有一個特殊的方法可以使用,那就是 GetBuffer,它的作用是返回一個可寫的緩衝指標。 
如果你只是打算修改字元或者截短字串,例如:
       CString s(_T("Char test "));
        LPTSTR p = s.GetBuffer(); 
        LPTSTR dot = strchr(p, ''.''); 
         // 在這裡新增使用p的程式碼
          if(p != NULL) 
         *p = _T('/0');
         s.ReleaseBuffer();                     // 使用完後及時釋放,以便能使用其它的CString成員函式
         在 GetBuffer 和 ReleaseBuffer 之間這個範圍,一定不能使用你要操作的這個緩衝的 CString 物件的任何方法。因為 
ReleaseBuffer 被呼叫之前,該 CString 物件的完整性得不到保障。

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常用資料型別使用轉換詳解
                               
                              先定義一些常見型別變數藉以說明
                              int i = 100;
                              long l = 2001;
                              float f=300.2;
                              double d=12345.119;
                              char username[]="女俠程佩君";
                              char temp[200];
                              char *buf;
                              CString str;
                              _variant_t v1;
                              _bstr_t v2;
                 一、其它資料型別轉換為字串
                              短整型(int)
                                     itoa(i,temp,10);     
                              //將i轉換為字串放入temp中,最後一個數字表示十進位制
                                     itoa(i,temp,2);      //按二進位制方式轉換 
                              長整型(long)
                                     ltoa(l,temp,10);

                 二、從其它包含字串的變數中獲取指向該字串的指標
                              CString變數
                              str = "2008北京奧運";
                              buf = (LPSTR)(LPCTSTR)str; 
                              BSTR型別的_variant_t變數
                              v1 = (_bstr_t)"程式設計師";
                              buf = _com_util::ConvertBSTRToString((_bstr_t)v1);
                 三、字串轉換為其它資料型別
                              strcpy(temp,"123"); 
                              短整型(int)
                                    i = atoi(temp); 
                              長整型(long)
                                    l = atol(temp); 
                              浮點(double)
                                    d = atof(temp);
                   四、其它資料型別轉換到CString
                              使用CString的成員函式Format來轉換,例如:
                              整數(int)
                                    str.Format("%d",i); 
                              浮點數(float)
                                    str.Format("%f",i); 
                              字串指標(char *)等已經被CString建構函式支援的資料型別可以直接賦值
                                    str = username;
                      五、BSTR、_bstr_t與CComBSTR
                              CComBSTR、_bstr_t是對BSTR的封裝,BSTR是指向字串的32位指標。
                              char *轉換到BSTR可以這樣: BSTR 
                              b=_com_util::ConvertStringToBSTR("資料");     
                              //使用前需要加上標頭檔案comutil.h
                              反之可以使用char *p=_com_util::ConvertBSTRToString(b);

                        六、VARIANT 、_variant_t 與 COleVariant
                              VARIANT的結構可以參考標頭檔案VC98/Include/OAIDL.H中關於結構體tagVARIANT的定義。
                              對於VARIANT變數的賦值:首先給vt成員賦值,指明資料型別,再對聯合結構中相同資料型別的變數賦值,舉個例子:
                              VARIANT va;
                              int a=2001;
                              va.vt=VT_I4;    //指明整型資料
                              va.lVal=a;      //賦值
                              對於不馬上賦值的VARIANT,最好先用Void VariantInit(VARIANTARG 
                              FAR* 
                              pvarg);進行初始化,其本質是將vt設定為VT_EMPTY,下表我們列舉vt與常用資料的對應關係:
                              unsigned char bVal; VT_UI1 
                              short iVal; VT_I2 
                              long lVal;  VT_I4  
                              float fltVal;  VT_R4 
                              double dblVal;  VT_R8  
                              VARIANT_BOOL boolVal;  VT_BOOL 
                              SCODE scode;  VT_ERROR 
                              CY cyVal;  VT_CY 
                              DATE date;  VT_DATE 
                              BSTR bstrVal;  VT_BSTR 
                              IUnknown FAR* punkVal;  VT_UNKNOWN 
                              IDispatch FAR* pdispVal;  VT_DISPATCH 
                              SAFEARRAY FAR* parray;  VT_ARRAY|* 
                              unsigned char FAR* pbVal;  VT_BYREF|VT_UI1 
                              short FAR* piVal;  VT_BYREF|VT_I2 
                              long FAR* plVal;  VT_BYREF|VT_I4 
                              float FAR* pfltVal;  VT_BYREF|VT_R4 
                              double FAR* pdblVal; VT_BYREF|VT_R8 
                              VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL 
                              SCODE FAR* pscode;  VT_BYREF|VT_ERROR 
                              CY FAR* pcyVal;  VT_BYREF|VT_CY 
                              DATE FAR* pdate; VT_BYREF|VT_DATE 
                              BSTR FAR* pbstrVal;  VT_BYREF|VT_BSTR 
                              IUnknown FAR* FAR* ppunkVal;  VT_BYREF|VT_UNKNOWN 
                              IDispatch FAR* FAR* ppdispVal; 
                              VT_BYREF|VT_DISPATCH 
                              SAFEARRAY FAR* FAR* pparray;  VT_ARRAY|* 
                              VARIANT FAR* pvarVal;  VT_BYREF|VT_VARIANT 
                              void FAR* byref;  VT_BYREF 
                              _variant_t是VARIANT的封裝類,其賦值可以使用強制型別轉換,其建構函式會自動處理這些資料型別。
                              例如:
                              long l=222;
                              ing i=100;
                              _variant_t lVal(l);
                              lVal = (long)i;
                              COleVariant的使用與_variant_t的方法基本一樣,請參考如下例子:
                              COleVariant v3 = "字串", v4 = (long)1999;
                              CString str =(BSTR)v3.pbstrVal;
                              long i = v4.lVal;
                      七、其它
                              對訊息的處理中我們經常需要將WPARAM或LPARAM等32位資料(DWORD)分解成兩個16位資料(WORD),例如:
                              LPARAM lParam;
                              WORD loValue = LOWORD(lParam);     //取低16位
                              WORD hiValue = HIWORD(lParam);     //取高16位 
                              對於16位的資料(WORD)我們可以用同樣的方法分解成高低兩個8位資料(BYTE),例如:
                              WORD wValue;
                              BYTE loValue = LOBYTE(wValue);     //取低8位
                              BYTE hiValue = HIBYTE(wValue);     //取高8位

                              如何將CString型別的變數賦給char*型別的變數
                              1、GetBuffer函式:
                              使用CString::GetBuffer函式。
                              char *p; 
                              CString str="hello"; 
                              p=str.GetBuffer(str.GetLength()); 
                              str.ReleaseBuffer();
                              將CString轉換成char * 時
                              CString str("aaaaaaa");
                              strcpy(str.GetBuffer(10),"aa");
                              str.ReleaseBuffer();

                              當我們需要字元陣列時呼叫GetBuffer(int  n),其中n為我們需要的字元陣列的長度.使用完成後一定要馬上呼叫ReleaseBuffer();
                              還有很重要的一點就是,在能使用const char *的地方,就不要使用char *
                              2、memcpy: 
                              CString mCS=_T("cxl"); 
                              char mch[20]; 
                              memcpy(mch,mCS,20); 
                              3、用LPCTSTR強制轉換: 儘量不使用
                              char *ch; 
                              CString str; 
                              ch=(LPSTR)(LPCTSTR)str; 
                              CString str = "good";
                              char *tmp;
                              sprintf(tmp,"%s",(LPTSTR)(LPCTSTR)str); 
                              4、
                              CString Msg; 
                              Msg=Msg+"abc"; 
                              LPTSTR lpsz; 
                              lpsz = new TCHAR[Msg.GetLength()+1]; 
                              _tcscpy(lpsz, Msg); 
                              char * psz; 
                              strcpy(psz,lpsz);

                              CString類向const char *轉換
                              char a[100];
                              CString str("aaaaaa");
                              strncpy(a,(LPCTSTR)str,sizeof(a));
                              或者如下:
                              strncpy(a,str,sizeof(a));
                              以上兩種用法都是正確地. 因為strncpy的第二個引數型別為const char 
                              *.所以編譯器會自動將CString類轉換成const char *.
                              CString轉LPCTSTR (const char *)
                              CString cStr;
                              const char *lpctStr=(LPCTSTR)cStr;
                              LPCTSTR轉CString
                              LPCTSTR lpctStr;
                              CString cStr=lpctStr;
                              將char*型別的變數賦給CString型的變數
                              可以直接賦值,如: 
                              CString myString = "This is a test"; 
                              也可以利用建構函式,如: 
                              CString s1("Tom");
                              將CString型別的變數賦給char []型別(字串)的變數
                              1、sprintf()函式
                              CString str = "good";
                              char tmp[200] ;
                              sprintf(tmp, "%s",(LPCSTR)str);  
                              (LPCSTR)str這種強制轉換相當於(LPTSTR)(LPCTSTR)str 
                              CString類的變數需要轉換為(char*)的時,使用(LPTSTR)(LPCTSTR)str 
                              然而,LPCTSTR是const char 
                              *,也就是說,得到的字串是不可寫的!將其強制轉換成LPTSTR去掉const,是極為危險的!
                              一不留神就會完蛋!要得到char 
                              *,應該用GetBuffer()或GetBufferSetLength(),用完後再呼叫ReleaseBuffer()。
                              2、strcpy()函式
                              CString str;
                              char c[256];
                              strcpy(c, str); 
                              char mychar[1024];
                              CString source="Hello";
                              strcpy((char*)&mychar,(LPCTSTR)source);

                              關於CString的使用
                              1、指定 CString 形參
                                  對於大多數需要字串引數的函式,最好將函式原型中的形參指定為一個指向字元 (LPCTSTR) 
                              而非 CString 的 const 指標。
                              當將形參指定為指向字元的 const 指標時,可將指標傳遞到 TCHAR 陣列(如字串 ["hi 
                              there"])或傳遞到 CString 物件。
                              CString 物件將自動轉換成 LPCTSTR。任何能夠使用 LPCTSTR 的地方也能夠使用 
                              CString 物件。
                              2、如果某個形參將不會被修改,則也將該引數指定為常數字符串引用(即 const 
                              CString&)。如果函式要修改該字串,
                              則刪除 const 修飾符。如果需要預設為空值,則將其初始化為空字串 [""],如下所示:
                              void AddCustomer( const CString& name, const 
                              CString& address, const CString& comment = "" ); 
                              3、對於大多數函式結果,按值返回 CString 物件即可。

                              串的基本運算
                                  對於串的基本運算,很多高階語言均提供了相應的運算子或標準的庫函式來實現。
                              為敘述方便,先定義幾個相關的變數:
                                  char 
                              s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;
                                  int result;
                                  下面以C語言中串運算介紹串的基本運算 
                              1、求串長
                                      int strlen(char *s);         //求串s的長度
                                  【例】printf("%d",strlen(s1));    //輸出s1的串長12
                              2、串複製
                                  char *strcpy(char 
                              *to,*from);//將from串複製到to串中,並返回to開始處指標
                                  【例】strcpy(s3,s1);  //s3="dir/bin/appl",s1串不變

                              3、聯接
                                  char *strcat(char *to,char 
                              *from);//將from串複製到to串的末尾,
                                                                    
                              //並返回to串開始處的指標
                                  【例】strcat(s3,"/");    //s3="dir/bin/appl/"
                                       strcat(s3,s2);     
                              //s3="dir/bin/appl/file.asm"
                              4、串比較
                                  int strcmp(char *s1,char *s2);//比較s1和s2的大小,
                                   //當s1<s2、s1>s2和s1=s2時,分別返回小於0、大於0和等於0的值 
                                  【例】result=strcmp("baker","Baker");    
                              //result>0
                                          result=strcmp("12","12");       
                              //result=0
                                          result=strcmp("Joe","joseph")   
                              //result<0
                              5、字元定位
                                  char *strchr(char *s,char 
                              c);//找c在字串s中第一次出現的位置,
                                                               
                              //若找到,則返回該位置,否則返回NULL
                                  【例】p=strchr(s2,'.');      //p指向"file"之後的位置
                                   if(p) strcpy(p,".cpp");     //s2="file.cpp" 
                                注意:
                                   ①上述操作是最基本的,其中後&