char char* std:string CString LPTSTR、LPCSTR、LPCTSTR、LPSTR
UNICODE:它是用两个字节表示一个字符的方法。比如字符'A'在ASCII下面是一个字符,可'A'在UNICODE下面是两个字符,高字符用0填充,而且汉字'程'在ASCII下面是两个字节,而在UNICODE下仍旧是两个字节。UNICODE的用处就是定长表示世界文字,据统计,用两个字节可以编 现存的所有文字而没有二义。
MBCS,它是多字节字符集,它是不定长表示世界文字的编 。MBCS表示英文字母时就和ASCII一 (这也是我们容易把MBCS和ASCII搞混的原 ),但表示其他文字时就需要用多字节。
WINDOWS下面的程序设计可以支持MBCS和UNICODE两种编码的字符串,具体用那种就看定义了MBCS宏还是UNICODE宏。MBCS宏对应的字符串指针是char*也就是LPSTR,UNICODE对应的指针是unsigned short*也就是LPWSTR,为了写程序方便微软定义了类型LPTSTR,在MBCS下他就是char*,在UNICODE下它是unsigned char*,这 就可以重定义一个宏进行不同字符集的转换了。
LPSTR: 32bit指针指向一个字符串,每个字符占1字节
LPCSTR: 32-bit指针指向一个常字符串,每个字符占1字节
LPCTSTR: 32-bit指针指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义
LPTSTR: 32-bit指针每字符可能占1字节或2字节,取决于Unicode是否定义
T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用 MBCS,也不明确表示使用 UNICODE。那到底使用哪种字符集 编译的时候才决定.
各种转换
char* 转化为 CString
现在你有一个 char* 类型的数据,或者说一个字符串。怎么样创建 CString 对象呢?这里有一些例子:
char * p = "This is a test";
或者象下面这样更具有 Unicode 意识:
TCHAR * p = _T("This is a test") 或 LPTSTR p = _T("This is a test");
你可以使用下面任意一种写法:
CString s = "This is a test"; // 8-bit only
CString s = _T("This is a test"); // Unicode-aware
CString s("This is a test"); // 8-bit only
CString s(_T("This is a test")); // Unicode-aware
CString s = p;
CString s(p);
CString 转换成char*
CString 转化成 char* 之一:强制类型转换为 LPCTSTR
LPCTSTR 操作符(或者更明确地说就是 TCHAR * 操作符)在 CString 类中被重载了,该操作符的定义是返回缓冲区的地址,因此,如果你需要一个指向 CString 的 字符串指针的话,可以这样做:
CString s("GrayCat");
LPCTSTR p = s;
所以参数传递的时候,如果形参是LPCSTR,可直接将一个CString的变量传递过去,不需要做任何转化。
CString转化成char* 之二:使用 CString 对象的 GetBuffer 方法
如果你需要修改 CString 中的内容,它有一个特殊的方法可以使用,那就是 GetBuffer(0),它的作用是返回一个可写的缓冲指针。 如果你只是打算修改字符或者截短字符串,你完全可以这样做:
CString s(_T("File.ext"));
LPTSTR p = s.GetBuffer(0);
LPTSTR dot = strchr(p, .); // OK, should have used s.Find...
if(p != NULL)
*p = _T(/0);
s.ReleaseBuffer();
必须强调一点,在 GetBuffer 和 ReleaseBuffer 之间这个范围,一定不能使用你要操作的这个缓冲的 CString 对象的任何方法。因为 ReleaseBuffer 被调用之前,该 CString 对象的完整性得不到保障。
注意:你试图把一个 LPCTSTR 类型的变量赋值给一个 LPTSTR 类型的变量,这种操作在C或C++中是被禁止的。你不能用这种方法 来滥用常量指针与非常量指针概念,否则,会扰乱编译器的优化机制,使之不知如何优化你的程序。在有些函数参数或者 类的成员变量 使用了 LPTSTR(不是LPCTSTR,中间是没有C的)。这个时候绝对不能用LPCTSTR,否则编译器就会报错。这时候要来一个二次转换。比如函数
::GetCurrentDirectory(DWORD nBufferLength,LPTSTR lpBuffer) ;
CString str;
::GetCurrentDirectory(MAX_PATH,(LPSTR)((LPCTSTR)str));
std::string 转化为char* 或const char* 可以用string.c_str()或string.data(),要注意区别
data()返回的指针指向一个字符数组,就是string.length()个字符不包括终止符"/0"。c_str()返回的指针指向一个C字符串,以'/0'结尾,字符数组长度为string.length()+1。