L表示long指針,這是為了兼容Windows 3.1等16位操作系統(tǒng)遺留下來的,在win32中以及其他的32為操作系統(tǒng)中, long指針和near指針及far修飾符都是為了兼容的作用,沒有實際意義。即win32中,long,near,far指針與普通指針沒有區(qū)別,LP 與P是等效的。
P表示這是一個指針。
T表示_T宏,這個宏用來表示你的字符是否使用UNICODE, 如果你的程序定義了UNICODE或者其他相關(guān)的宏,那么這個字符或者字符串將被作為UNICODE字符串,否則就是標準的ANSI字符串。
STR表示這個變量是一個字符串。
C表示是一個常量,const。
LPTSTR: 如果定義了UNICODE宏則LPTSTR被定義為LPWSTR。typedef LPTSTR LPWSTR;
否則LPTSTR被定義為LPSTR。 typedef LPTSTR LPSTR;
下面列出一些常用的typedefs:
類型 MBCS Unicode
WCHAR wchar_t wchar_t
LPSTR char* char*
LPCSTR const char* const char*
LPWSTR wchar_t* wchar_t*
LPCWSTR const wchar_t* const wchar_t*
TCHAR char wchar_t
LPTSTR TCHAR*(或char*) TCHAR* (或wchar_t*)
LPCTSTR const TCHAR* const TCHAR*
由于Win32 API文檔的函數(shù)列表使用函數(shù)的常用名字(例如, SetWindowText"),所有的字符串都是用TCHAR來定義的。(除了XP中引入的只適用于Unicode的API)。所以結(jié)論,在 VS2005系統(tǒng)中,為提高可移植性,定義字符串時用TCHAR,轉(zhuǎn)化為UNICODE時用_T而不用L。
錯誤 1 error C2664: “CWnd::MessageBoxW”: 不能將參數(shù) 1 從“const char [3]”轉(zhuǎn)換為“LPCTSTR”
1、覺得很煩,一般的做法就是不管三七二十一,在字符串前面加一個‘L’:
如調(diào)用函數(shù)FUN(LPCTSTR str)時,不能 FUN("HELLO"); 而是FUN(L"HELLO");
通常這樣做都比較能解決問題。
2、或者還可以用_T(), 即 FUN(_T("HELLO")); _T() 的別名還有 _TEXT(), TEXT()。
稍微研究了下,BSTR,LPSTR,LPWSTR,LPCTSTR,LPTSTR等這些讓人頭暈的東東。(還是C#里簡單啊,直接tostring)
BSTR:是一個OLECHAR*類型的Unicode字符串,是一個COM字符串,帶長度前綴,與VB有關(guān),沒怎么用到過。
LPSTR:即 char *,指向以'/0'結(jié)尾的8位(單字節(jié))ANSI字符數(shù)組指針
LPWSTR:即wchar_t *,指向'/0'結(jié)尾的16位(雙字節(jié))Unicode字符數(shù)組指針
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
3、相互轉(zhuǎn)換方法:
LPWSTR->LPTSTR: W2T();
LPTSTR->LPWSTR: T2W();
LPCWSTR->LPCSTR: W2CT();
LPCSTR->LPCWSTR: T2CW();
ANSI->UNICODE: A2W();
UNICODE->ANSI: W2A();
另外,CString轉(zhuǎn)為CStringW方法(通過一個wchar_t數(shù)組來轉(zhuǎn))
CString str;
CStringW strw;
wchar_t *text = new wchar_t[sizeof(wchar_t) * str.GetLength()];
MultiByteToWideChar(CP_ACP,0,str,-1,text,str.GetLength());
strw = text;
4、另外,還可以強行轉(zhuǎn)換,不過不一定能成功
5、還有_bstr_t ( 對BTSTR的封裝,需要#include<comdef.h> ),也可將單字節(jié)字符數(shù)組指針轉(zhuǎn)為雙字節(jié)字符數(shù)組指針,還沒怎么沒用到過。
==========================================================
DWORD本來被定義為unsigned long,DWORD的含義就是雙字,一個字是2字節(jié),雙字就是32字節(jié)。 但是在C/C++中,經(jīng)常會用到把一個指針轉(zhuǎn)換成數(shù)字儲存,然后再將其傳喚為指針調(diào)用。那么在32位系統(tǒng)下,指針是32位長度的,在64位系統(tǒng)下,指針是64位長度的,所以微軟引入了DWORD_PTR和INT_PTR等帶_PTR的類型,這些類型是這么保證的:將指針轉(zhuǎn)換成帶_PTR的類型然后再轉(zhuǎn)換回來,可以得到原始的指針,不會發(fā)生截斷。在實現(xiàn)上,DWORD_PTR在32位程序和64位程序的定義是不同的,32位定位為unsigned long,64位定義為unsigend __int64。 基于這個要求,你最好使用C#提供的類似的功能: System.UIntPtr 這個數(shù)據(jù)類型對應(yīng)C語言里面帶_PTR的類型,保證程序在32位平臺和64位平臺,以及今后會出現(xiàn)的128位平臺都可以正常運行。
1.CString:動態(tài)的TCHAR數(shù)組。它是一個完全獨立的類,封裝了“+”等操作符和字符串操作方法,換句話說就是CString是對TCHAR操作的方法的集合。
2.LPCTSTR:常量的TCHAR指針,其定義為
1 | typedef const TCHAR * LPCTSTR |
其中
L表示long指針 這是為了兼容Windows 3.1等16位操作系統(tǒng)遺留下來的,在win32中以及其他的32位操作系統(tǒng)中, long指針和near指針及far修飾符都
是為了兼容的作用。沒有實際意義。
P表示這是一個指針
C表示是一個常量
T表示在Win32環(huán)境中, 有一個_T宏
STR表示這個變量是一個字符串
。
2.LPTSTR:TCHAR指針,其定義為
1 | typedef TCHAR * LPTSTR |
L、P、T的含義同上。
3.TCHAR:TCHAR其實是一個宏,其定義為:
1 | #ifdef UNICODE |
2 | typedef wchar_t TCHAR ; |
3 | #else |
4 | typedef char TCHAR ; |
5 | #endif |
也就是說,如果我們使用unicode編碼,那么TCHAR指的就是wchat_t,如果我們使用的是ASCII編碼,那么TCHAR指的就是char,這樣處理的目的是為了程序的可移植性。T表示在Win32環(huán)境中, 有一個_T宏 。
4.WCHAR:WCHAR其實也是一個宏,表示的就是wchar_t,為了書寫方便重新定義的一個宏而已,其定義為:
1 | typedef wchar_t WCHAR |
5.string:string是c++中的字符串變量,因為操作c類型的char非常麻煩,而且很容易出現(xiàn)內(nèi)存泄漏,所以c++就對c中的char 進行了封裝,其中
1 | 包含了賦值、刪除、增加等常用操作,這些操作都不用考慮內(nèi)存,是的使用更加方便,所以能使用string就盡量使用string,使用string要包含其頭文件: |
1
#include <string>
1 | 注意不是: |
1 | #include <string.h> |
因為string.h是C字符串頭文件。
01 | a) =,assign() //賦以新值 |
02 | b) swap() //交換兩個字符串的內(nèi)容 |
03 | c) +=,append(),push_back() //在尾部添加字符 |
04 | d) insert() //插入字符 |
05 | e) erase() //刪除字符 |
06 | f) clear() //刪除全部字符 |
07 | g) replace() //替換字符 |
08 | h) + //串聯(lián)字符串 |
09 | i) ==,!=,<,<=,>,>=,compare() //比較字符串 |
10 | j) size(),length() //返回字符數(shù)量 |
11 | k) max_size() //返回字符的可能最大個數(shù) |
12 | l) empty() //判斷字符串是否為空 |
13 | m) capacity() //返回重新分配之前的字符容量 |
14 | n) reserve() //保留一定量內(nèi)存以容納一定數(shù)量的字符 |
15 | o) [ ], at() //存取單一字符 |
16 | p) >>,getline() //從stream讀取某值 |
17 | q) << //將謀值寫入stream |
18 | r) copy() //將某值賦值為一個C_string |
19 | s) c_str() //將內(nèi)容以C_string返回 |
20 | t) data() //將內(nèi)容以字符數(shù)組形式返回 |
21 | u) substr() //返回某個子字符串 |
22 | v)查找函數(shù) |
23 | w)begin() end() //提供類似STL的迭代器支持 |
24 | x) rbegin() rend() //逆向迭代器 |
25 | y) get_allocator() //返回配置器 |
1 | |
1 | 6. wchar_t : wchar_t 是c++中用來表示寬字節(jié)的數(shù)據(jù)類型,即unicode編碼的數(shù)據(jù)類型。 |
1 | 7. char : char 是c中的字符數(shù)據(jù)類型,屬于ASCII編碼。 |
1 | 下面是msdn上給出的定義: |
01 | type Meaning in MBCS builds Meaning in Unicode builds |
02 |
03 | WCHAR wchar_t wchar_t |
04 | LPSTR char * char * |
05 | LPCSTR const char * const char * |
06 | LPWSTR wchar_t * wchar_t * |
07 | LPCWSTR const wchar_t * const wchar_t * |
08 | TCHAR char wchar_t |
09 | LPTSTR TCHAR * TCHAR * |
10 | LPCTSTR const TCHAR * const TCHAR * |
1 | 既然有定義了這么多的數(shù)據(jù)類型,所以他們之間的相互轉(zhuǎn)化是少不了的。 |
1 | A):CString的轉(zhuǎn)化 |
1 | 1.CString和 LPCTSTR 的轉(zhuǎn)化: |
1 | CString和 LPCTSTR 不需要轉(zhuǎn)化,兩者是等價的,所以: |
1 | CString str( "cstring" ); |
2 | LPCTSTR pcStr = str; |
2.CString和LPTSTR的轉(zhuǎn)化:
下述轉(zhuǎn)法雖然可以,但是卻不安全:
1 | CString str( "string" ); |
2 | LPTSTR pStr = ( LPTSTR )( LPCTSTR )(str); |
因為本來轉(zhuǎn)化后的字符串變得可以修改了,造成了安全隱患。
正確的轉(zhuǎn)化方法為:
1 | CString str( "string" ); |
2 | LPTSTR pStr = str.GetBuffer(); |
3 | str.ReleaseBuffer(); |
1 | 注意:GetBuffer()和ReleaseBuffer()之間不可以調(diào)用任何的CString函數(shù),比如GetLength()函數(shù),因為無法預(yù)測對內(nèi)存的操作,所以任何CString函數(shù)得到的 |
1 | 結(jié)果都是不確定的。 |
1 | |
3.CString和WCHAR*(wchar_t*)的轉(zhuǎn)化
方法一:使用wcscpy()函數(shù)
1 | CString str( "string" ); |
2 | WCHAR pWchar[100]; |
3 | wcscpy(pWchar,str); |
方法二:使用wcscpy_s()函數(shù)
這個函數(shù)是上一個函數(shù)的安全版本,調(diào)用上一個函數(shù)如果pWchar的內(nèi)存不足時,容易引發(fā)意味的錯誤,但是wcscpy_s()則不會,應(yīng)該其內(nèi)存大小已經(jīng)指定出來了:
1 | CString str( "string" ); |
2 | WCHAR pWchar[100]; |
3 | wcscpy(pWchar,100,str); |
方法三:使用_tcscpy()函數(shù)
1 | CString str( "string" ); |
2 | WCHAR pStr[100]; |
3 | _tcscpy(pStr,str); |
方法四:使用_tcscpy_s()函數(shù)
同wcscpy_s()一樣,_tcscpy_s()函數(shù)也是_tcscpy()函數(shù)的安全版本:
1 | CString str( "string" ); |
2 | WCHAR pStr[100]; |
3 | _tcscpy_s(pStr,100,str); |
1 | |
4.CString和char*的轉(zhuǎn)化
方法一:使用wcstombs()函數(shù)
1 | CString str( "string" ); |
2 | char pChar[100]; |
3 | wcstombs (pChar,str,100); |
方法二:使用wcstombs_s()函數(shù)
同上面一樣,wcstombs_s()是wcstombs()的安全版本:
上面一會使用strcpy(),一會使用wcscpy(),一會又使用_tcscpy(),這三者有什么關(guān)系呢,其實strcpy()處理的就是 ASCII編碼的字符,像char,而wcscpy()處理的是Unicode 編碼,_tcscpy()則是一個宏,如果你使用的是ASCII編碼,那么_tcscpy()表示的就是strcpy(),如果你使用的是Unicode 編碼,那么_tcscpy()表示的就是wcscpy(),這可以通過定義_UNICODE或UNICODE宏來實現(xiàn)。你可能已經(jīng)知道了為什么要定義這么 一個宏,對!就是為了代碼的移植。還有一個函數(shù)就是wcstombs(),這個函數(shù)是干什么用的呢?其實除了Unicode編碼,還有一個編碼,那就是多 字節(jié)編碼,通常用的是雙字節(jié)編碼,vc就支持這種編碼,函數(shù)wcstombs()就是為了實現(xiàn)多字節(jié)和單字節(jié)轉(zhuǎn)換而設(shè)計的。
聯(lián)系客服