程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> ANSI與UINCODE編碼,ANSIUINCODE編碼

ANSI與UINCODE編碼,ANSIUINCODE編碼

編輯:C++入門知識

ANSI與UINCODE編碼,ANSIUINCODE編碼


簡要說明:
  • ANSI是一種字符代碼,為使計算機支持更多語言,通常使用 0x80~0xFF 范圍的 2 個字節來表示 1 個字符。
  • Uincode(統一碼、萬國碼、單一碼)是計算機科學領域裡的一項業界標准,包括字符集、編碼方案等。Unicode 是為了解決傳統的字符編碼方案的局限而產生的,它為每種語言中的每個字符設定了統一並且唯一的二進制編碼,以滿足跨語言、跨平台進行文本轉換、處理的要求。1990年開始研發,1994年正式公布。

 

優缺點:
  • Ansi用char表示一個字符,占用一個字節儲存空間。所以Ansi字符碼最多支持255個字符,表示英文還可以,但對於中文、日文、韓文等語言來說就不夠用了。
  • Uincode用unsigned short表示一個字符,定義成wchar_t,占用兩個字節儲存空間。所以Uincode字符碼基本支持90%的自然語言。缺點:空間占用翻倍,網絡傳輸量變大。

 


 

ANSI碼 = 窄字符

Uincode = 寬字符

 

 


 

◆字符碼數據類型:

● Ansi: char、char * 、const char *                  C++

     CHAR、(PCHAR、PSTR、LPSTR)、LPCSTR           VC++

 

● Unicode: wchar_t、wchar_t * 、const wchar_t *

     WCHAR、(PWCHAR、PWSTR、LPWSTR)、LPCWSTR

 

● T 通用類型: TCHAR、(TCHAR * 、PTCHAR、PTSTR、LPTSTR)、LPCTSTR 

 

以上,其中:P代表指針的意思,STR代表字符串的意思,L是長指針的意思,在WIN32平台下可以忽略,C代表const常量的意思,W代表wide寬字節的意思,T大家可以理解為通用類型的意思,  

通用類型是微軟為了方便使用定義的通用字符類型,在不同的編碼環境下,會根據是否定義了_UINCODE宏,自動會轉化為char 或 wchar_t;

 


 

◆ 字符串類型的對象的定義:

● Ansi:char *pAnsiStr = "hello";

● Unicode:wchar_t *pUnicodeStr = L"hello";

● 通用類型:TCHAR *pTStr = _T("hello"); 或者 TCHAR *pTStr = _TEXT("hello");

● 動態申請內存:TCHAR *pszBuf = new TCHAR[100];                  //標示符很重要

 

其中,_TEXT 和 _T 是一樣的,定義如下:

#define _T(x)       __T(x) 

#define _TEXT(x)    __T(x)

//來看看 __T 的最終定義: 

#ifdef  _UNICODE 

#define __T(x)      L##x       //轉換Uincode

#else 

#define __T(x)      x         //等於本身

#endif

 

其中,##為連接起來的意思。

 


◆ 常用的字符串處理函數,具體信息見MSDN:

字符串長度:

● Ansi:strlen(char *str);                //獲取字符串長度,cs為cstring縮寫,len為length,w,_t字符串類型。方便記憶。也可以查詢MSDN

● Unicode:wcslen(wchar_t *str);

● 通用函數:_tcslen(TCHAR *str);

 

● Ansi:int atoi(const char *str);            //轉換為數字,atoi,_wtoi,_tstoi.可以按照不同的顏色去記憶。分別為字符串類型+to+轉換類型。

● Unicode:int _wtoi(const wchar_t *str);

● 通用函數:_tstoi(const TCHAR *str);

 

字符串拷貝:

● Ansi:strcpy(char *strDestination, const char *strSource); //獲取字符串長度,cs為cstring縮寫,cpy為copy,w,_t字符串類型。方便記憶。也可以查詢MSDN

● Unicode:wcscpy(wchar_t *strDestination, const wchar_t *strSource);

● 通用函數:_tcscpy(TCHAR *strDestination, const TCHAR *strSource);

 

以上函數不安全,在vs2003等以上版本的編譯器中會有warnning警告提示,以下為安全函數(vc++6.0不支持):

● Ansi:strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource);//_s可以理解為safe縮寫,保險的。

● Unicode:wcscpy_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource);

● 通用函數:_tcscpy_s(TCHAR *strDestination, size_t numberOfElements, const TCHAR *strSource);

 

numberOfElements Size of the destination string buffer. 目的緩沖區的大小,以字節為單位,不是字符!

 

size_t unsigned integer,在MSDN中的解釋:Result of sizeof operator,也就是說 size_t 是 unsigned integer 即無符號整數。那為什麼會有size_t這個類型呢? 因為不同平台的操作系統(32/64)中 int/long 等類型所占的字節並不一樣,而 size_t 在不同的平台下有不同的定義。有點類似於TCHAR類型:

#ifndef   _SIZE_T_DEFINED   

  #ifdef     _WIN64   

  typedef   unsigned   __int64         size_t;   //8個字節,64位  

  #else   

  typedef   _W64   unsigned   int       size_t;   //4個字節,32位   

  #endif   

  #define   _SIZE_T_DEFINED 

#endif

 

 


 

◆ 字符串占用字節數:

● Ansi:

char szStr[] = "abc";

占用字節數求法:sizeof(szStr);

 

char *psz = "defgh";

占用字節數求法:strlen(psz)*sizeof(char);

 

● Unicode:

wchar_t szwStr[] = L"abc";

占用字節數求法:sizeof(szwStr);

 

wchar_t *pwsz = L"defgh";

占用字節數求法:wcslen(pwsz)*sizeof(wchar_t);

 

● 通用函數:

TCHAR szStr[] = _T("abc");

占用字節數求法:sizeof(szStr);

 

TCHAR *psz = _T("defgh");

占用字節數求法:_tcslen(psz)*sizeof(TCHAR);


◆轉換用到的最根本的 API 函數:

WideCharToMultiByte 實現寬字節轉換到窄字節          //函數參數自行查詢MSDN。

MultiByteToWideChar 實現窄字節轉換到寬字節          

 

WideCharToMultiByte 的代碼頁用來標記與新轉換的字符串相關的代碼頁;

MultiByteToWideChar 的代碼頁用來標記與一個多字節字符串相關的代碼頁,

 

[1]、常用的代碼頁有 CP_ACP 和 CP_UTF8 兩個: 使用 CP_ACP 代碼頁就實現了 ANSI 與 Unicode 之間的轉換;

    使用 CP_UTF8 代碼頁就實現了 UTF-8 與 Unicode 之間的轉換。

[2]、dwFlags 參數允許我們進行額外的控制,但是,一般情況下都不使用這個標志,直接傳遞 0 就行了。

[3]、lpDefaultChar和pfUsedDefaultChar:

只有當WideCharToMultiByte函數遇到一個寬字節字符,而該字符在uCodePage參數標識的代碼頁中並沒有它的表示法時,WideCharToMultiByte函數才使用這兩個參數。如果寬字節字符不能被轉換,該函數便使用lpDefaultChar參數指向的字符。如果該參數是NULL(這是大多數情況下的參數值),那麼該函數使用系統的默認字符。該默認字符通常是個問號。這對於文件名來說是危險的,因為問號是個通配符。pfUsedDefaultChar參數指向一個布爾變量,如果Unicode字符串中至少有一個字符不能轉換成等價多字節字符,那麼函數就將該變量置為TRUE。如果所有字符均被成功地轉換,那麼該函數就將該變量置為FALSE。當函數返回以便檢查寬字節字符串是否被成功地轉換後,可以測試該變量。

● 兩個轉換函數的使用舉例:

char *cctryWideCharToAnsi(wchar_t *pWideChar)
{
	if (!pWideChar) return NULL;
	char *pszBuf = NULL;
	int needBytes = WideCharToMultiByte(CP_ACP, 0, pWideChar, -1, NULL, 0, NULL, NULL);
	if (needBytes > 0){
		pszBuf = new char[needBytes+1];
		ZeroMemory(pszBuf, (needBytes+1)*sizeof(char));
		WideCharToMultiByte(CP_ACP, 0, pWideChar, -1, pszBuf, needBytes, NULL, NULL);
	}

	return pszBuf;
}

wchar_t *cctryAnsiCharToWide(char *pChar)
{
	if (!pChar) return NULL;
	wchar_t *pszBuf = NULL;
	int needWChar = MultiByteToWideChar(CP_ACP, 0, pChar, -1, NULL, 0);
	if (needWChar > 0){
		pszBuf = new wchar_t[needWChar+1];
		ZeroMemory(pszBuf, needWChar+1);
		MultiByteToWideChar(CP_ACP, 0, pChar, -1, pszBuf, needWChar);
	}

	return pszBuf;
}

 使用過後千萬別忘記釋放空間

◆宏轉換

 A2W、W2A、T2A、T2W 宏的使用以及注意事項:
[1]、使用 alloca() 函數進行空間的申請,宏返回的地址空間是從棧上面申請的,那麼以後就不必釋放,這樣就涉及到了一個作用域的問題,具體見MSDN,
大家可以簡單的理解為“向下兼容”.
[2]、不要在一個函數的循環體中使用 A2W 等字符轉換宏,可能引起棧溢出。
比如:

#include <atlconv.h>
void func()
{
    while(true)
    {
        {
            USES_CONVERSION;
            testFunc(A2W("abc"));
        }
    }
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved