九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
windows編程中字符和字符串的處理

windows編程中字符和字符串的處理

分類: wince 筆記 WIN32編程 65人閱讀 評(píng)論(0) 收藏 舉報(bào)

字符格式基礎(chǔ)

首先說(shuō)說(shuō)字符編碼的兩種格式。

一種是將文本字符串編碼成一組以0結(jié)尾的單字節(jié)字符,即ansi字符,每個(gè)字符占8位,即一個(gè)字節(jié)。這種編碼方式的缺陷是,對(duì)于字符本地化的問(wèn)題不能很好的解決,因?yàn)?位空間最多容納256個(gè)字符,不能完全唯一的表示世界上所有的字符。

另一種是Unicode字符,每個(gè)字符都使用UTF-16編碼(一般來(lái)說(shuō),除非特別聲明不使用UTF-16編碼),即一個(gè)字符占16位空間(2字節(jié))。基于這種情況,世界上大多數(shù)語(yǔ)言的字符都可以用一個(gè)唯一的2字節(jié)空間表示。

傳統(tǒng)的ansi字符在C語(yǔ)言中用char數(shù)據(jù)類型表示(1字節(jié))。在源代碼中聲明一個(gè)字符串,則編譯器會(huì)轉(zhuǎn)換為由8位char數(shù)據(jù)類型構(gòu)成的一個(gè)數(shù)組(以"/0"結(jié)尾)

char c='a';//一個(gè)8位的字符

char szbuffer[100]="a string";//含有99個(gè)8位字符和1個(gè)8位結(jié)束符(/0)的數(shù)組

微軟的c/c++編譯器為unicode定義了一個(gè)內(nèi)建的數(shù)據(jù)結(jié)構(gòu),wchar_t,它表示一個(gè)16位的unicode(UTF-16)字符。

wchar_t c=L'a';//一個(gè)16位的字符

wchar_t szbuffer[100]=L"a string";//含有99個(gè)16位字符和1個(gè)16位結(jié)束符(/0)的數(shù)組

此外,windows為了和c語(yǔ)言加以區(qū)別,則定義了自己的數(shù)據(jù)類型。

//WinNT.h

typedef char CHAR;//一個(gè)8位的字符

typedef wchar_t WCHAR;//一個(gè)16位的字符

typedef CHAR *PCHAR;//指向8位字符的指針

typedef CHAR *PSTR;//指向8位字符的指針

typedef CONST CHAR *PCSTR;//指向8位字符的常量指針

typedef WCHAR *PWCHAR;//指向16位字符的指針

typedef WCHAR *PWSTR;//指向16位字符的指針

typedef CONST WCHAR *PCWSTR;//指向16位字符的常量指針

在實(shí)際使用中,使用哪種類型并不重要,但最好保持一致,這樣有利于維護(hù)。另外如果是windows編程,最好使用windows定義的數(shù)據(jù)類型,這樣可與MSDN保持一致,有利于開(kāi)發(fā)。

windows還定義了如下宏和通用數(shù)據(jù)類型,來(lái)方便開(kāi)發(fā)人員。

#ifdef UNICODE

typedef WCHAR TCHAR ,*PTCHAR,PTSTR;

typedef CONST WCHAR *PCTSTR;

#define __TEXT(quote) quote

#define __TEXT(quote) L##quote

#else

typedef CHAR TCHAR ,*PTCHAR,PTSTR;

typedef CONST CHAR *PCTSTR;

#define __TEXT(quote) quote

#endif

#define __TEXT(quote) L##quote

其中黑體部分的類型都是通用數(shù)據(jù)類型,即無(wú)論使用ansi還是unicode,都能通過(guò)編譯。

TCHAR c=TEXT('A');//如果定義了unicode,則a是16位字符;如果定義了ansi,則a是8位字符

TCHAR SZBUFFER[100]=TEXT("A STRING");//如果定義了unicode,則SZBUFFER中的字符為16位;否則,字符位8位。

自windowsNT開(kāi)始,windows所有版本都使用unicode構(gòu)建。即如果我們的程序使用ansi字符,那么操作系統(tǒng)將會(huì)執(zhí)行轉(zhuǎn)換為unicode,這些轉(zhuǎn)換都是對(duì)用戶透明的,且會(huì)產(chǎn)生時(shí)間和內(nèi)存的開(kāi)銷。所以,我們應(yīng)盡量使用unicode構(gòu)建程序。

至此為止,總結(jié)一下,就是定義字符用TCHAR,指針類型使用*TCHAR足以,定義字面值用_T宏。

windows中的函數(shù)的參數(shù)列表中如果有字符串,則該函數(shù)通常有兩個(gè)版本,一個(gè)ansi,一個(gè)unicode。例如CreateWindowEx接受這兩種類型的字符串作為參數(shù)。實(shí)際上,CreateWindowEx只是一個(gè)宏,定義如下:

//WinUser.h

#ifdef UNICODE
#define CreateWindowEx  CreateWindowExW
#else
#define CreateWindowEx  CreateWindowExA
#endif

很明顯,這和前面的通用數(shù)據(jù)類型使用的是同一伎倆。其中CreateWindowExW接受Unicode,CreateWindowExA接受ansi。

在windows vista中,CreateWindowExA只是一個(gè)轉(zhuǎn)換層,負(fù)責(zé)分配內(nèi)存,然后將ansi轉(zhuǎn)換為unicode,然后在內(nèi)部調(diào)用CreateWindowExW。

C運(yùn)行庫(kù)中的安全字符串處理函數(shù)

通常,修改字符串的函數(shù)都存在一個(gè)安全隱患,即目標(biāo)字符串的緩沖不夠大,則會(huì)導(dǎo)致內(nèi)存中的數(shù)據(jù)被破壞。

例如:

WCHAR szbuffer[3]=L"";

wcscpy(szbuffer,L"abc");

以上的例子是以0結(jié)尾的,需要szbuffer[4]才可以容納。但編譯時(shí)并不會(huì)有任何報(bào)錯(cuò)或警告。

針對(duì)以上問(wèn)題,我們必須使用“安全字符串處理函數(shù)”,這一類的函數(shù)以_s結(jié)尾(secure之意),我們來(lái)看一下這類函數(shù)的原型.

PTSTR _tcscpy(PTSTR strDestination,PCTSTR strSource);

errno_t _tcscpy_s(PTSTR strDestination,size_t numberOfCharacters,PCTSTR strSource);

PTSTR _tcscat(PTSTR strDestination,PCTSTR strSource);

errno_t  _tcscat_s(PTSTR strDestination,size_t numberOfCharacters,PCTSTR strSource);

可以看到,在將一個(gè)緩沖區(qū)作為目標(biāo)緩沖區(qū)時(shí),必須提供這個(gè)緩沖區(qū)的大小(可容納的字符個(gè)數(shù)),通過(guò)調(diào)用_countof宏計(jì)算出來(lái)。

這個(gè)緩沖區(qū)大小參數(shù)的主要任務(wù)就是驗(yàn)證緩沖區(qū)是否足以容納結(jié)果數(shù)據(jù).

現(xiàn)在,我們調(diào)用這些安全函數(shù)的時(shí)候,就可以檢查返回的errno_t值。只有返回S_OK值,才表明函數(shù)調(diào)用成功。其他的值可以參照errno.h中的定義。

來(lái)看一個(gè)例子:

TCHAR szbuffer[3]=L"";

_tcscpy_s(szbuffer,_countof(szbuffer),_T("abc"));

執(zhí)行完后, szbuffer的第一個(gè)字符被設(shè)置為'/0',而其他所有字節(jié)全部被設(shè)置為0xfd(填充符)。

在處理字符串時(shí)獲得更多的控制

除了安全字符串處理函數(shù),c運(yùn)行庫(kù)還增加了一些函數(shù),用于在處理字符串時(shí)獲得更多的控制。例如,可以控制如何截?cái)嘧址?/p>

這類函數(shù)具有兩個(gè)版本,對(duì)應(yīng)ansi和unicode。

HRESULT StringCchCat( LPTSTR pszDest,size_t cchDest,LPCTSTR pszSrc);

HRESULT StringCchCatEx( LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc,LPTSTR *ppszDestEnd,size_t *pcchRemaining,DWORD dwFlags);

HRESULT StringCchCopy( LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc);

HRESULT StringCchCopyEx(LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc, LPTSTR *ppszDestEnd,size_t *pcchRemaining,DWORD dwFlags);

可以看出,在所有方法的名稱中,都含有一個(gè)“Cch”,這表示count of characters,即字符個(gè)數(shù)。通常使用_countof宏獲得。

另外還有一些函數(shù)含有“cb”,這表示函數(shù)要求用字節(jié)數(shù)來(lái)指定大小。通常使用sizeof()獲得。

這些函數(shù)返回HRESULT,具體的值

S_OK 成功。目標(biāo)緩沖區(qū)中包含源字符串,并以/0終止
STRSAFE_E_INVALID_PARAMETER 失敗。將NULL傳給了一個(gè)參數(shù)
STRSAFE_E_INSUFFICIENT_BUFFER 失敗。指定的目標(biāo)緩沖區(qū)太小,無(wú)法容納整個(gè)源字符串


不同于安全字符串處理函數(shù),這類函數(shù)運(yùn)行時(shí),當(dāng)緩沖區(qū)太小,則會(huì)執(zhí)行截?cái)唷?/p>

windows字符串處理函數(shù)

在shlwapi.h定義了大量好用的字符串函數(shù),可以用來(lái)對(duì)操作系統(tǒng)有關(guān)的數(shù)值進(jìn)行格式化操作。

在實(shí)際編程中,經(jīng)常需要比較兩個(gè)字符串是否相等。對(duì)于這樣的需求可以使用CompareString(Ex)或者CompareStringOrdinal。

CompareString(Ex)一般用于向用戶顯示的字符串。

CompareStringOrdinal一般用于比較程序內(nèi)部的字符串,如路徑名,注冊(cè)表項(xiàng)值等。

CompareString(Ex)的處理速度相對(duì)于CompareStringOrdinal較慢。

這兩個(gè)函數(shù)的返回0,則表示調(diào)用失敗;

返回1(CSTR_LESS_THAN)表明string1小于string2;

返回2(CSTR_GREATER_THAN)表明string1大于string2.


使用unicode的好處:

1、有利于應(yīng)用程序的本地化。

2、代碼執(zhí)行效率更高,因?yàn)閣indows基于unicode構(gòu)建,如果我們也保持一致,則windows處理時(shí)不必耗費(fèi)額外的資源轉(zhuǎn)換。

3、容易與com集成

4、容易與.net集成


推薦的字符處理方式

1、使用通用數(shù)據(jù)類型和宏,如TCHAR和_T

2、將字符串想象成字符的數(shù)組,而非char或字節(jié)的數(shù)組。

3、與字符串有關(guān)的計(jì)算需修改。尤其要搞清楚很多的函數(shù)要求傳遞的是字符數(shù)還是字節(jié)數(shù),如是前者,則用_countof()獲取;如是后者,則用(字符數(shù)*sizeof(字符類型))獲取。

4、避免使用printf系列函數(shù)轉(zhuǎn)換ansi和unicode。正確的做法是使用MultiByteToWideChar或WideCharToMultiByte。


5、始終使用安全的字符串處理函數(shù),_s或stringcch,如要控制截?cái)啵瑒t使用后者。

6、如果一個(gè)緩沖區(qū)處理函數(shù)的參數(shù)中不包括目標(biāo)緩沖區(qū)的長(zhǎng)度,那么避免使用。

7、比較字符串時(shí),使用CompareStringOrdina和CompareString(Ex)。前者速度快,適合處理程序內(nèi)部的字符串;后者用于處理UI的字符串,因?yàn)樗且詤^(qū)域設(shè)置來(lái)適當(dāng)排序,速度較慢。

 

本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/shentao17792/archive/2010/02/21/5314312.aspx

分享到:
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
關(guān)于char, wchar_t, TCHAR, _T(),L,宏 _T、TEXT,_TEXT、L
VC Windows平臺(tái)字符透明編程大總結(jié)
LPWSTR,LPCTSTR,LPTSTR
VC知識(shí)庫(kù)文章 - VC++的Unicode編程
Unicode簡(jiǎn)介
【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、...
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服