VC 中的Unicode程式設計

2021-05-25 14:17:42 字數 4458 閱讀 5237

整理了一下蒐集的有關vc++中的unicode程式設計問題,如char、wchar_t、tchar、_t等。

原帖:

windows早在windows2000以後的版本裡使用unicode進行全系統開發了,也就是用於建立視窗、顯示文字、進行字串操作等所有核心函式都需用unicode字串。可我們在進行windows程式設計時基本上沒有考慮這個問題,這也就所謂的相容能力,但這是付出了代價的,比如你傳遞乙個ansi字串給使用unicode字串的函式,那麼系統首先會把字串轉換成unicode,然後把unicode傳遞給作業系統,如果希望函式返回ansi字串,那麼系統會把unicode字串轉換成ansi字串,然後將結果返回給你的應用程式。所有這些轉換操作都是在你看不到的情況下進行的。這都是需要占用系統時間和記憶體的。

所以,今後的程式應該盡量使用unicode來進行編碼,那麼如何在windows平台下進行unicode編碼呢?microsoft為unicode設計了windows api。只需要在你的源**裡定義兩個巨集(unicode和_unicode)就來使用unicode編碼了。那麼這兩個巨集是怎麼作用的呢?

首先讓我們來看看_unicode巨集:

我們都知道標準c標頭檔案string.h裡定義了乙個wchar_t的資料型別,它就是乙個unicode字元的資料型別。

typedef unsigned short wchar_t;

例如,你可以定義乙個unicode的字元陣列像這樣:wchar_t szbuffer[100];

該語句所占用的空間不是100個位元組,而是200個。當然像strcpy、strcat、strchr等字串操作的常見函式也是無法對unicode使用的,所以也有一組補充的函式:

char *strcat(char *, const char *);

wchar_t *wcscat(wchar_t *, const wchar_t *);

char *strchr(const char *, int);

wchar_t *wcschr(const wchar_t *, wchar_t);

char *strcpy(char *, const char *);

wchar_t *wcscpy(wchar_t *, const wchar_t);

int strcmp(const char *, const char *);

int wcscmp(const wchar_t *, const wchar_t *);

size_t strlen(const char *);

size_t wcslen(const wchar_t *);

可以發現所有的unicode函式開頭都有wcs這幾個字母,wcs是寬字串的英文縮寫——width char string。那如果我的**中即有char型的內容,也有wchar_t的內容,比如pm讓我修改乙份源**,裡面以前用的是char型,而現在pm要求所有新增的**都用wchar_t型該怎麼辦呢?怎麼在乙份源**裡即允許char的,又可以編譯wchar_t呢?這個時候就可以包含tchar.h這個標頭檔案。tchar.h裡就是一組巨集,用於相容ansi和unicode的。這個時候你就不要呼叫str或wcs類的函式了,直接使用tchar.h裡的通用巨集就可以了。如果在編譯的源**檔案裡定義了_unicode巨集,那麼tchar.h裡的這組巨集就會引用wcs這組函式,否則就引用str的這組。

比如在tchar.h中有_tcscpy這個巨集,如果沒有定義_unicode巨集,那麼它就會呼叫strcpy函式,如果定義了就呼叫wcscpy函式。

你甚至可以使用tchar.h中定義的通用字元型別tchar。如果定義了_unicode,那麼tchar的宣告就是這樣的:typedef wchar_t tcahr;

如果沒有定義_unicode,那麼宣告就是:typedef char tchar;

用tchar來定義字串像這樣:tchar szstring[100];

也可以建立字串指標:tchar *szerror = "error";

上面這樣定義編譯器會把後面的字串當作unicode嗎?vc++編譯器的預設設定是把他們當作ansi字元的,因此,如果沒有定_unicode,那麼tchar就是char型的,沒有什麼問題,如果定義了_unicode,上面這行就會出錯,因為給wchar_t賦值的是乙個char型的字串,那我想給它賦值為wchar_t型怎麼辦呢?只需要這樣:tchar *szerror = l"error";

前面加乙個大寫的l就行了。告訴編譯器這個字串是乙個unicode。但現在又有問題,如果我像上面這樣寫,那麼只有在定義了_unicode時才能正確編譯,否則將會報錯啊,誰也沒看到過這種字串的定義啊!所以為了解決這個問題在tchar.h中定義了另乙個巨集_t,如果定義了_unicode,那麼_t巨集定義如下:#define _t(x) l##x。如果沒有定義_unicode,那麼_t巨集定義如下:#define _t(x) x。

那下面就讓我們來看看這個巨集的強大吧!以後再定義字串不用糾結於上面的問題了,直接這麼寫:tchar *szerror = _t("error");

_t也可以用於定義單個字元,比如:szerror[0] = _t('a');

vc++裡設定_unicode巨集:

接著讓我們看看unicode巨集吧:

windows標頭檔案定義了幾個unicode的資料型別:

wchar——unicode字元

pwstr——指向unicode字串的指標

pcwstr——指向乙個const型別的unicode字串的指標

我們都知道windows的api經常提供兩套函式原型,比如createwindowex函式,就有兩套原型createwindowexw和createwindowexa。初學者很少注意這個,因為我們都是直接用createwindowex函式的,誰管它有幾套原型呢!不過現在就讓我們來關注一下吧。其實這兩個原型基本上一致:

其實就是乙個是unicode的,乙個是ansi的。我們可以看看winuser.h裡對createwindowex的巨集定義其實是這樣的:

#ifdef unicode

#define createwindowex createwindowexw

#else

#define createwindowex createwindowexa

#endif

有了這個定義,那麼你只需要呼叫createwindowex函式就行了,在需要用unicode時就在源**前面定義乙個unicode就行了,不需要去修改createwindowex函式。

這只是乙個例子,windows提供的api大多數都是類似這樣的定義,如字串操作的一組函式windows也給出了通用的api:

lstrcat——將乙個字串置於另乙個字串的結尾處

lstrcmp——對兩個字串進行區分大小寫的比較

lstrcmpi——對兩個字串進行不區分大小寫的比較

lstrcpy——將乙個字串拷貝到記憶體中的另乙個位置

lstrlen——返回字串的長度(按字元數來計算,而不是位元組數)

以上的函式當定義了unicode巨集時會擴充套件為unicode版,沒有定義unicode時會擴充套件為ansi版。

還有一些轉換字元大小寫的函式,比如在c庫里的tolower和toupper函式是無法正確轉換unicode字元的,那麼就必須呼叫windows定義的函式來轉換:

ptstr charlower(ptstr pszstring);

ptstr charupper(ptstr pszstring);

也可以轉換單個字元:

tchar clowerchar = charlower((ptstr)szstring[0]);

還有些類似的函式,比如:

dword charlowerbuffer(ptstr pszstring, dword cchstring);

dword charupperbuffer(ptstr pszstring, dword cchstring);

bool ischaralpha(tchar ch);

bool ischaralphanumeric(tchar ch);

bool ischarlower(tchar ch);

bool ischarupper(tchar ch);

注意:不管是不是用tchar和_t,都不能讓ansi和unicode混存。最後從一開始就直接unicode。

superarhow

說: 不要再使用tchar和_t了!如果您正開始乙個新的專案,請無論如何也要頂住壓力,直接使用unicode編碼!切記!您只需要對您的組員進行10分鐘的培訓,記住strcpy用 wcscpy,sprintf用swprintf代替,常數前加l,就可以了!它不會花您很多時間的,帶給您的是穩定和安全!相信偶,沒錯的!

VC中的Unicode程式設計

vc中的unicode程式設計 在windows下程式設計還是支援unicode吧,大勢所趨啊,window 2k以後的系統底層都是基於unicode的,就算你呼叫ansi的api 以a結尾比如setwidowstexta 系統也會在你的程序預設堆上動態分配一塊記憶體,存放轉換後的unicode字串...

用VC6進行UNICODE程式設計

1.新增 unicode 和 unicode 預處理定義 位置 project settings c c preprocessor definitions 新增了這兩個定義後,mfc的一些內建型別如 tchar cstring 都將轉為支援寬字元型別 wchar t char tchar char ...

用VC6進行UNICODE程式設計

1.新增 unicode 和 unicode 預處理定義 位置 project settings c c preprocessor definitions 新增了這兩個定義後,mfc的一些內建型別如 tchar cstring 都將轉為支援寬字元型別 wchar t 2.使用寬字元相關型別,如 ch...