vs2010字符集問題

2021-06-27 05:44:59 字數 4367 閱讀 9243

問題由來:cserialport串列埠類使用時出現各種函式呼叫引數錯誤。

問題確認:

vc2005及更高版本預設使用unicode字符集,cstring裡存的是寬字元,也就是wchar_t,而不再是char。你可以這麼寫:

strdate.format(_t("%4d-%2d-%2d"),st.wyear,st.wmonth,st.wday);

strtime.format(_t("%4d:%2d:%2d"),st.whour,st.wminute,st.wsecond);

以後寫程式的時候,定義字串變數,不要用char*,而用tchar*。所有字串常量,不要直接用"",而要用_t("")。舉個例子:

tchar* str = _t( "hello, world" );

messagebox( _t( "hello" ));

當然,我上面說的是在mfc裡面。寫控制台程式的話,就不用了。

字元編碼問題詳細說明:
一.ansi和unicode

2.ansi字元和unicode字元

ansi字元型別為char,指向字串的指標pstr(lpstr),指向乙個常數字串的指標pcstr(lpcstr);

對應的windows定義的unicode字元型別為wchar(typedef wchar wchar_t) ,指向unicode字串的指標pwstr ,指向乙個常數unicode字串的指標pcwstr 。

ansi 「ansi」

unicode l「unicode」

ansi/unicode t(「string」)或_text(「string」)

3.ansi字元和unicode字串的操作

雙位元組(dbcs)字符集中,字串的每個字元可以包含乙個或兩個位元組。如果只是呼叫strlen()函式,那麼你就無法知道字串到底有多少個字元,它只能告訴你到達結尾的0之前有多少個位元組。

標準c中的strcpy,strchr,strcat等只能用於ansi字串,不能正確處理unicode字串,因此也提供了一組補充函式,功能等價,但用於unicode碼。我們來看看string .h字串標頭檔案中是怎樣處理char*和wchar_t*兩個字串版本的:

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

wchar_t *wcschr(wchat_t*,const wchar_t *)

類似的還有strchr/wcschr,strcmp/wcscmp,strlen/wcslen etc.

ansi 操作函式以str開頭 strcpy

unicode 操作函式以wcs開頭 wcscpy

mbcs 操作函式以_mbs開頭 _mbscpy

ansi/unicode 操作函式以_tcs開頭 _tcscpy(c執行期庫)

ansi/unicode 操作函式以lstr開頭 lstrcpy(windows函式)

二.ansi/unicode通用字元/字串型別tchar/lptstr/lpctstr

neutral ansi/unicode types

1.通用字元型tchar

tchar

ifdef unicode it is wchar_t(wchar)for unicode platforms;

else it is char for ansi and dbcs platforms.

2.通用字串指標lptstr

lptstr

ifdef unicode it is lpwstr(*wchar_t) for unicode platforms;

else it is lpstr (*char) for ansi and dbcs platforms.

3.通用通用常數字串指標lpctstr

lpctstr

ifdef unicode it is lpcwstr(*const wchar_t) for unicode platforms;

else it is lpcstr (*const char)for ansi and dbcs platforms.

typedef lpwstr lp;

#define __text(quote) l##quote // r_winnt

<1>_unicode巨集用於c執行期標頭檔案,unicode巨集則用於windows標頭檔案,當編譯**模組時,通常必須同時定義這兩個巨集。

<2>如果定義了_unicode,若要生成乙個unicode字串,字串前要加l巨集,用於告訴編譯器該字串應該作為unicode字串來編譯處理。但是這樣又有個問題就是如果沒有定義_unicode則編譯出錯。為了解決這個問題我們必須用到_text巨集,這個巨集也在tchar.h中做了定義。使用該巨集後,無論原始檔有沒有定義_unicode都不會出現編譯錯誤。

<3>unicode與ansi字串的轉換:windows函式multibytetowidechar函式用於將多位元組字串轉換成寬字串,函式widechartomultibyte將寬字串轉換成等價的多位元組字串。

有的人愛用strcpy等標準ansi函式,有的人愛用_t***x函式,有必要把來龍去脈搞清楚。 為了搞清這些函式,就必須理請幾種字元型別的寫法。char就不用說了,先說一些wchar_t。wchar_t是unicode字元的資料型別,它實際定義在裡:

typedef unsigned short wchar_t;

不能使用類似strcpy這樣的ansi c字串函式來處理wchar_t字串,必須使用wcs字首的函式,例如wcscpy。為了讓編譯器識別unicode字串,必須以在前面加乙個「l」,例如:

wchar_t *sztest=l"this is a unicode string."

wchar_t是unicode字元的資料型別,它實際定義在裡:

typedef unsigned short wchar_t;

下面在看看tchar。如果你希望同時為ansi和unicode編譯的源**,那就要include tchar.h。tchar是定義在其中的乙個巨集,它視你是否定義了_unicode巨集而定義成char或者wchar_t。如果你使用了tchar,那麼就不應該使用ansi的str***函式或者unicode的wcs***函式了,而必須使用tchar.h中定義的_tcs***函式。另外,為了解決剛才提到帶「l」的問題,tchar.h中定義了乙個巨集:「_text」。

以strcpy函式為例子,總結一下:

.如果你想使用ansi字串,那麼請使用這一套寫法:

char szstring[100];

strcpy(szstring,"test");

.如果你想使用unicode字串,那麼請使用這一套:

wchar_t szstring[100];

wcscpyszstring,l"test");

.如果你想通過定義_unicode巨集,而編譯ansi或者unicode字串**:

tchar szstring[100];

_tcscpy(szstring,_text("test"));

2, ansi與unicode

unicode稱為寬字元型字串,com裡使用的都是unicode字串。

將ansi轉換到unicode

(1)通過l這個巨集來實現,例如: clsidfromprogid( l"mapi.folder",&clsid);

(2)通過multibytetowidechar函式實現轉換,例如:

char *szprogid = "mapi.folder";

wchar szwideprogid[128];

clsid clsid;

long llen = multibytetowidechar(cp_acp,0,szprogid,strlen(szprogid),szwideprogid,sizeof(szwideprogid));

szwideprogid[llen] = '

(3)通過a2w巨集來實現,例如:

uses_conversion;

clsidfromprogid( a2w(szprogid),&clsid);

將unicode轉換到ansi

(1)使用widechartomultibyte,例如:

// 假設已經有了乙個unicode 串 wszsomestring...

char szansistring [max_path];

widechartomultibyte ( cp_acp, wc_compositecheck, wszsomestring, -1, szansistring, sizeof(szansistring), null, null );

(2)使用w2a巨集來實現,例如:

uses_conversion;

ptemp=w2a(wszsomestring);

VS2010字串相加的問題

cstring 有兩個 的運算子過載,乙個接受 lpctstr 型別的引數,用於在當前 cstring 物件的末尾追加乙個字串 另乙個接受 tchar 型別的引數,用於在當前 cstring 物件的末尾追加乙個字元。uint 不能隱式轉換為 tchar 型別,也不能隱式轉換為 lpctstr,所以編...

vs2010設定問題

1.help libary不能選擇以瀏覽器或者視窗的形式開啟,切換不方便 解決辦法 拷貝整個microsoft help viewer覆蓋以前的檔案,覆蓋後可能會遇到vs中f1幫助或者選單欄裡的選項失效,需要手動啟動help libary 解決。vs的help libary有多個版本,不同版本間存在...

MySQL(九) 字符集

編碼 字元 二進位制 解碼 二進位制 字元 為什麼會出現亂碼?因為編碼和解碼的規則不同。本質上都是同樣的一串二進位製流,按照不同的規則解讀的結果當然是不同的。模擬一下我們的時間戳轉時間的場景,時間戳就好比是二進位制,時區就好比是不同的字符集,同乙個時間戳用不同的時區轉換,得到的結果當然是不同的。所以...