日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多字节与宽字节

發布時間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多字节与宽字节 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 多字節字符集(MBCS,Multi-Byte?Chactacter?Set):指用多個字節來表示一個字符的字符編碼集合。一般英文字母用1Byte,漢語等用2Byte來表示。兼容ASCII?127。

在最初的時候,Internet上只有一種字符集——ANSI的ASCII字符集,它使用7?bits來表示一個 字符,總共表示128個字符,其中包括了 英文字母、數字、標點符號等常用字符。

為了擴充ASCII編碼,以用于顯示本國的語言,不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼,又稱為"MBCS(Muilti-Bytes Charecter Set,多字節字符集)"。

不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。一個很大的缺點是,同一個編碼值,在不同的編碼體系里代表著不同的字。這樣就容易造成混亂。導致了unicode碼的誕生。

  • 寬字節字符集:一般指Unicode編碼的字符集,

Unicode稱為統一碼或萬國碼,統一了不同國家的字符編碼。

Unicode通常用兩個字節表示一個字符,原有的英文編碼從單字節變成雙字節,只需要把高字節全部填為0就可以。

為了統一所有文字的編碼,Unicode應運而生。Unicode把所有語言都統一到一套編碼里,這樣就不會再有亂碼問題了。

Unicode固然統一了編碼方式,但是它的效率不高,比如UCS-4(Unicode的標準之一)規定用4個字節存儲一個符號,那么每個英文字母前都必然有三個字節是0,這對存儲和傳輸來說都很耗資源。為了提高Unicode的編碼效率,于是就出現了UTF-8編碼。UTF-8可以根據不同的符號自動選擇編碼的長短。比如英文字母可以只用1個字節就夠了。

UTF是“Unicode Transformation Format”的縮寫,可以翻譯成Unicode字符集轉換格式,即怎樣將Unicode定義的數字轉換成程序數據。用char、char16_t、char32_t分別表示無符號8位整數,無符號16位整數和無符號32位整數。UTF-8、UTF-16、UTF-32分別以char、char16_t、char32_t作為編碼單位。(注: char16_t 和 char32_t 是 C++ 11 標準新增的關鍵字。如果你的編譯器不支持 C++ 11 標準,請改用 unsigned short 和 unsigned long。)“漢字”的UTF-8編碼需要3個字節。“漢字”的UTF-16編碼需要兩個char16_t,大小是2個字節。“漢字”的UTF-32編碼需要兩個char32_t,大小是4個字節。

普通字符、字符串前加 L 就變成寬字符 wchar_t 存儲(用2Byte存1個字符)了,例如,L‘看’,L"abc啊";或_T("sf飛")


MFC中的 CString 與 std::string 的轉換:

1. 使用Unicode字符集時,CString等價于CStringW;使用多字節字符集時,CString相對于CStringA

2. CString --> std::string

// 1. Unicode下 CString --> std::string // 方法1 CString str = L"sdf"; std::string s = CT2A(str.GetString());// GetString()比較新的VS有,舊可以用GetBuffer()std::string s = CT2A(str.GetBuffer());str.ReleaseBuffer(); // 方法2 CString str = L"dshf"; CStringA stra(str); std::string s(stra); //或 std::string s(CStringA(str));//方法3 USES_CONVERSION; CString str = L"djg"; std::string s = W2A(str); //首先str--》const wchar_t* ,然后W2A將const wchar_t*--》const char*, //最后用const char*初始化s

?

?3. std::string --> CStringW / std::wstring

std::string s("dhhh"); CStringW strw(CStringA(s.c_str()); std::wstring sw(strw);

  


1)TCHAR 轉換為const wchar_t *,直接強制轉換,在TCHAR前面加上(*const?wchar_t)

2)BSTR:是一個OLECHAR*類型的Unicode字符串,是一個COM字符串,帶長度前綴,與VB有關,沒怎么用到過。?

LPSTR:即 char *,指向以'/0'結尾的8位(單字節)ANSI字符數組指針?

LPWSTR:即wchar_t *,指向'/0'結尾的16位(雙字節)Unicode字符數組指針?

?LPCSTR:即const char *?

?LPCWSTR:即const wchar_t *?

LPTSTR:LPSTR、LPWSTR兩者二選一,取決于是否宏定義了UNICODE或ANSI?

LPCTSTR: LPCSTR、LPCWSTR兩者二選一,取決于是否宏定義了UNICODE或ANSI,

如下是從MFC庫中拷來的:

#ifdef UNICODE typedef LPWSTR LPTSTR; typedef LPCWSTR LPCTSTR; #else typedef LPSTR LPTSTR; typedef LPCSTR LPCTSTR; #endif

  

?相互轉換方法:

LPWSTR->LPTSTR:    ? W2T();
?LPTSTR->LPWSTR:    ?T2W();?
LPCWSTR->LPCSTR:   W2CT();
?LPCSTR->LPCWSTR:   T2CW();
?ANSI->UNICODE:   A2W();
?UNICODE->ANSI:   W2A();

3)

LPWSTR轉為LPCSTR

LPCSTR=CW2A(LPWSTR);

?4)

CString與LPCWSTR的轉化(http://www.cnblogs.com/foolboy/archive/2005/07/25/199869.html)

問題起因:?
??? 在寫WritePrivateProfileString寫.ini配置文件時在msdn中看到,如果想要寫的配置信息即時生效,必須在之前使用WritePrivateProfileStringW來re-read一下目標.ini文件,其原文如下:?

// force the system to re-read the mapping into shared memory // so that future invocations of the application will see it // without the user having to reboot the system WritePrivateProfileStringW( NULL, NULL, NULL, L"appname.ini" );

  

??? 查了一下msdn中WritePrivateProfileStringW的原型如下:?

WINBASEAPI BOOL WINAPI WritePrivateProfileStringW ( LPCWSTR lpAppName, //section []中的字符串LPCWSTR lpKeyName, // key “=”左邊的字符串LPCWSTR lpString, //寫入的內容LPCWSTR lpFileName ) // 配置文件的路徑 例如: [section] key=string

  其中的每個參數的類型都為LPCWSTR,實際中獲得的文件名都為CString,問題產生。?

問題分析:

LPCWSTR 是Unicode字符串指針,初始化時串有多大,申請空間就有多大,以后存儲若超過則出現無法預料的結果,這是它與CString的不同之處。而CString是一個串類,內存空間類會自動管理。LPCWSTR?初始化如下:?

LPCWSTR Name=L"TestlpCwstr";

????由于LPCWSTR必須指向Unicode的字符串,問題的關鍵變成了Anis字符與Unicode字符之間的轉換,不同編碼間的轉換,通過查找資料可知,可以ATL中轉換宏可以用如下方法實現:?

//方法一 CString str=_T("TestStr"); USES_CONVERSION; LPWSTR pwStr=new wchar_t[str.GetLength()+1]; wcscpy(pwStr,T2W((LPCTSTR)str));// 方法二 CString str=_T("TestStr"); USES_CONVERSION; LPWCSTR pwcStr = A2CW((LPCSTR)str);

??MFC中CString和LPSTR是可以通用,其中A2CW表示(LPCSTR)? -> (LPCWSTR),USER_CONVERSION表示用來定義一些中間變量,在使用ATL的轉換宏之前必須定義該語句。?
??? 順便也提一下,如果將LPCWSTR轉換成CString,那就更加容易,在msdn中的CString類說明中提到了可以直接用LPCWSTR來構造CString,所以可以進行如下的轉換代碼:???

LPCWSTR?pcwStr?=?L"TestpwcStr";?
CString?str(pcwStr);

問題總結:?????
????在頭文件<atlconv.h>中定義了ATL提供的所有轉換宏,如:????

??A2CW ? ? ?(LPCSTR)??->?(LPCWSTR)?
??A2W????????(LPCSTR)??->?(LPWSTR)?
??W2CA ? ? (LPCWSTR)?->?(LPCSTR)?
??W2A????????(LPCWSTR)?->?(LPSTR)

?????所有的宏如下表所示:?

A2BSTROLE2AT2AW2A
A2COLEOLE2BSTRT2BSTRW2BSTR
A2CTOLE2CAT2CAW2CA
A2CWOLE2CTT2COLEW2COLE
A2OLEOLE2CWT2CWW2CT
A2TOLE2TT2OLEW2OLE
A2WOLE2WT2WW2T

上表中的宏函數,非常的有規律,每個字母都有確切的含義如下:

2to 的發音和 2 一樣,所以借用來表示“轉換為、轉換到”的含義。
AANSI 字符串,也就是 MBCS。
W、OLE寬字符串,也就是 UNICODE。
T中間類型T。如果定義了 _UNICODE,則T表示W;如果定義了 _MBCS,則T表示A
Cconst 的縮寫

??? 利用這些宏,可以快速的進行各種字符間的轉換。使用前必須包含頭文件,并且申明USER_CONVERSION;使用 ATL 轉換宏,由于不用釋放臨時空間,所以使用起來非常方便。但是考慮到棧空間的尺寸(VC 默認2M),使用時要注意幾點:?
??? 1、只適合于進行短字符串的轉換;?
??? 2、不要試圖在一個次數比較多的循環體內進行轉換;?
??? 3、不要試圖對字符型文件內容進行轉換,因為文件尺寸一般情況下是比較大的;?
??? 4、對情況 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();

MultiByteToWideChar() 和 WideCharToMultiByte()的用法:
www.cnblogs.com/ranjiewen/p/5770639.html

int MultiByteToWideChar(UINT CodePage, //指定執行轉換的多字節字符所使用的字符集,CP_ACP:ANSI字符集,CP_UTF8:UTF-8字符集DWORD dwFlags, // 一般為NULLLPCSTR lpMultiByteStr, // [in] 要被轉換的字符指針int cchMultiByte, // lpMultiByteStr指針指向的字符串的長度,若字符串以\0結尾,可簡單寫為 -1LPWSTR lpWideCharStr, //[out] 輸出的寬字符串指針int cchWideChar // 指定由參數lpWideCharStr指向的緩沖區的寬字符數。若此值為0,函數不會執行轉換,而是返回目標緩存lpWideChatStr所需的寬字符數。);int WideCharToMultiByte( UINT CodePage, //指定執行轉換的字符集 DWORD dwFlags, // NULL LPCWSTR lpWideCharStr, // 待轉換的字符串 int cchWideChar, // 待轉換的字符串長度,若以空字符結尾,則可寫-1 LPSTR lpMultiByteStr, // 指向接收被轉換字符串的緩沖區 int cbMultiByte, // 緩沖區的長度,若為0,函數返回接收的緩沖區的長度 LPCSTR lpDefaultChar, // NULL LPBOOL lpUsedDefaultChar //NULL );

  

轉載于:https://www.cnblogs.com/htj10/p/11027323.html

總結

以上是生活随笔為你收集整理的多字节与宽字节的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。