關於wchar_t
在C++標準中,wchar_t是寬字元類型,每個wchar_t類型佔2個位元組,16位寬。漢字的表示就要用到wchar_t 。char,我們都知道,佔一個位元組,8位寬。
標準C++中的wprintf()函數以及iostream類庫中的類和對象能提供wchar_t寬字元類型的相關操作。
locale loc( "chs" );//定義“地區設定”為中文方式
wcout.imbue( loc );//載入中文字元輸入方式
wchar_t str[]=L"中國";//定義寬字元數組,注意L是大寫
wcout<<str<<endl;//顯示寬字元數組,下同
wprintf(str);
system("pause");
wchar_t 轉換為char 的代碼如下:
有如下的wchar_t和char變數
wchar_t w_cn = '中';
char c_cn[2] = {'0'} ;
char *C2W(wchar_t w_cn , char c_cn[2])
{
//following code convert wchar to char
c_cn[0] = w_cn >> 8 ;
c_cn[1] = w_cn ;
c_cn[2] = '\0';
return c_cn ;
}
其中需要注意的是一個16位的wchar_t需要用兩個8位的char來儲存之。我們可以發現另外一個問題,wchar_t的高位位元組應該儲存在char數組的低位位元組。
wchar_t *類型 轉為char *類型
CString strName("listen");
char *pcstr = (char *)new char[2 * strName.GetLength()+1] ;
WideCharToMultiByte( CP_ACP,
0,
strName, // 要轉換的wchar_t*
-1,
pcstr, // 接收char*的緩衝區指標
2 * strName.GetLength()+1, // pcstr的緩衝區的大小
NULL,
NULL );
關於system("command")
system("command")是執行一個dos命令。system("pause")就是執行Dos命令pause,等待使用者輸入。
system("pause") 與getchar()區別
system("pause") 是調用WINDOWS CONSOLE APP下的命令 PAUSE的。
system("const char*")就是調用WINDOWS CONSOLE APP下的命令。
比如system("exit");
system("ping 192.168.0.1")等等
而getchar()只是C標準庫裡等待一個字元的函數,兩者區別很大。
/*---------------------------------------------------*/
如何使system("pause") 不彈出“按任意鍵繼續”這幾個字呢?
用system("pause>nul") 就可以了
wchar_t*,wchar_t,wchat_t數組,char,char*,char數組,std::string,std::wstring,CString
#include <string>
// 使用CString必須使用MFC,並且不可包含<windows.h>
#define _AFXDLL
#include <afx.h>
using namespace std;
//----------------------------------------------------------------------------------
//將 單位元組char* 轉換為 寬位元組 wchar*
inline 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*
inline 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
inline void Ascii2WideString( const std::string& szStr, std::wstring& wszStr )
{
int nLength = MultiByteToWideChar( CP_ACP, 0, szStr.c_str(), -1, NULL, NULL );
wszStr.resize(nLength);
LPWSTR lpwszStr = new wchar_t[nLength];
MultiByteToWideChar( CP_ACP, 0, szStr.c_str(), -1, lpwszStr, nLength );
wszStr = lpwszStr;
delete [] lpwszStr;
}
//----------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
char* pChar = "我喜歡char";
wchar_t* pWideChar = L"我討厭wchar_t";
wchar_t tagWideCharList[100] ;
char ch = 'A';
char tagChar[100] = {NULL};
CString cStr;
std::string str;
// 註:設定語言環境以便輸出WideChar
setlocale(LC_ALL,"chs");
// 註: char* 轉換 wchar_t*
// 註: wchar_t 未重載 << ,所以不可使用 cout << 輸出
pWideChar = AnsiToUnicode( pChar );
// 註:printf("%ls") 和 wprintf(L"%s") 一致
printf( "%ls\n", pWideChar );
// 註:wchar_t* 轉換 wchar_t[]
wcscpy ( tagWideCharList, pWideChar );
wprintf( L"%s\n", tagWideCharList );
// 註:wchar_t[] 轉換 wchar_t*
pWideChar = tagWideCharList;
wprintf( L"%s\n", pWideChar );
// 註:char 轉換 string
str.insert( str.begin(), ch );
cout << str << endl;
// 註:wchar_t* 轉換 string
pWideChar = new wchar_t[str.length()];
swprintf( pWideChar, L"%s", str.c_str());
wprintf( L"%s\n", pWideChar );
// 註:string 轉換 char*
pChar = const_cast<char*>(str.c_str());
cout << pChar << endl;
// 註:char* 轉換 string
str = std::string(pChar);
// 註: cout 的 << 重載了string, 若printf 的話必須 printf("%s", str.c_str());
// 而不可 print( "%s", str ); 因為 str 是個 string 類
cout << str << endl;
// 註:string 轉換 char[]
str = "無聊啊無聊";
strcpy( tagChar, str.c_str() );
printf( "%s\n", tagChar );
// 註:string 轉換 CString;
cStr = str.c_str();
// 註:CString 轉換 string
str = string(cStr.GetBuffer(cStr.GetLength()));
// 註:char* 轉換 CString
cStr = pChar;
// 註:CString 轉換 char*
pChar = cStr.GetBuffer( cStr.GetLength() );
// 註:CString 轉換 char[]
strncpy( tagChar, (LPCTSTR)CString, sizeof(tagChar));
// 註:CString 轉換 wchar_t*
pWideChar = cStr.AllocSysString();
printf( "%ls\n", pWideChar );
}
WideCharToMultiByte()函數
函數功能:該函數映射一個unicode字串到一個多位元組字串。
函數原型:int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, LPCSTR lpMultiByteStr, int cchMultiByte, LPCSTR lpDefaultChar, PBOOL pfUsedDefaultChar );
參數:
CodePage:指定執行轉換的字碼頁,這個參數可以為系統已安裝或有效任何字碼頁所給定的值。你也可以指定其為下面的任意一值:
CP_ACP:ANSI字碼頁;CP_MACCP:Macintosh字碼頁;CP_OEMCP:OEM字碼頁;
CP_SYMBOL:符號字碼頁(42);CP_THREAD_ACP:當前線索ANSI字碼頁;
CP_UTF7:使用UTF-7轉換;CP_UTF8:使用UTF-8轉換。
dwFlags:一組位標記用以指出是否未轉換成預作或寬字元(若組合形式存在),是否使用表意字元替代控制字元,以及如何處理無效字元。你可以指定下面是標記常量的組合,含義如下:
MB_PRECOMPOSED:通常使用預作字元——就是說,由一個基底字元和一個非Null 字元組成的字元只有一個單一的字元值。這是預設的轉換選擇。不能與
MB_COMPOSITE值一起使用。
MB_COMPOSITE:通常使用組合字元——就是說,由一個基底字元和一個非Null 字元組成的字元分別有不同的字元值。這是預設的轉換選擇。不能與MB_PRECOMPOSED值一起使用。
MB_ERR_INVALID_CHARS:如果函數遇到無效的輸入字元,它將運行失敗,且GetLastErro返回ERROR_NO_UNICODE_TRANSLATION值。
MB_USEGLYPHCHARS:使用表意字元替代控制字元。
組合字元由一個基礎字元和一個非Null 字元構成,每一個都有不同的字元值。每個預作字元都有單一的字元值給基礎/非Null 字元的組成。在字元è中,e就是基礎字元,而重音符標記就是非Null 字元。
函數的預設動作是轉換成預作的形式。如果預作的形式不存在,函數將嘗試轉換成組合形式。
標記MB_PRECOMPOSED和MB_COMPOSITE是互斥的,而標記MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS則不管其它標記如何都可以設定。
lpWideCharStr:指向將被轉換的unicode字串。
cchWideChar:指定由參數lpWideCharStr指向的緩衝區的字元個數。如果這個值為-1,字串將被設定為以NULL為結束符的字串,並且自動計算長度。
lpMultiByteStr:指向接收被轉換字串的緩衝區。
cchMultiByte:指定由參數lpMultiByteStr指向的緩衝區最大值(用位元組來計量)。若此值為零,函數返回lpMultiByteStr指向的目標緩衝區所必需的位元組數,在這種情況下,lpMultiByteStr參數通常為NULL。
lpDefaultChar和pfUsedDefaultChar:只有當WideCharToMultiByte函數遇到一個寬位元組字元,而該字元在uCodePage參數標識的字碼頁中並沒有它的標記法時,WideCharToMultiByte函數才使用這兩個參數。如果寬位元組字元不能被轉換,該函數便使用lpDefaultChar參數指向的字元。如果該參數是NULL(這是大多數情況下的參數值),那麼該函數使用系統的預設字元。該預設字元通常是個問號。這對於檔案名稱來說是危險的,因為問號是個萬用字元。pfUsedDefaultChar參數指向一個布爾變數,如果Unicode字串中至少有一個字元不能轉換成等價多位元組字元,那麼函數就將該變數置為TRUE。如果所有字元均被成功地轉換,那麼該函數就將該變數置為FALSE。當函數返回以便檢查寬位元組字串是否被成功地轉換後,可以測試該變數。
傳回值:如果函數運行成功,並且cchMultiByte不為零,傳回值是由 lpMultiByteStr指向的緩衝區中寫入的位元組數;如果函數運行成功,並且cchMultiByte為零,傳回值是接收到待轉換字串的緩衝區所必需的位元組數。如果函數運行失敗,傳回值為零。若想獲得更多錯誤資訊,請調用GetLastError函數。它可以返回下面所列錯誤碼:
ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;
ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。
注意:指標lpMultiByteStr和lpWideCharStr必須不一樣。如果一樣,函數將失敗,GetLastError將返回ERROR_INVALID_PARAMETER的值。
ANSI和UNICODE編碼
二者都是字元代碼的一種表示形式
ANSI編碼用0x88~0xFF範圍的2個位元組來表示1個字元。
Unicode編碼是國際組織指定的可以容納世界上所有文字和服的字元的字元編碼方案。用數字0~0x10FFFF來映射這些字元。
我的理解:說白了,ANSI編碼是單位元組,Unicode編碼是寬字元。
本文來自學步園,轉載請標明出處:http://www.xuebuyuan.com/199513.html