zoukankan      html  css  js  c++  java
  • 【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR

    L表示long指针,这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用,没有实际意义。即win32中,long,near,far指针与普通指针没有区别,LP 与P是等效的。

    P表示这是一个指针。

    T表示_T宏,这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为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文档的函数列表使用函数的常用名字(例如, SetWindowText"),所有的字符串都是用TCHAR来定义的。(除了XP中引入的只适用于Unicode的API)。所以结论,在 VS2005系统中,为提高可移植性,定义字符串时用TCHAR,转化为UNICODE时用_T而不用L。

     

     

    首先在编译程序时经常会遇到这种问题:

    错误 1 error C2664: “CWnd::MessageBoxW”: 不能将参数 1 从“const char [3]”转换为“LPCTSTR”

    1、觉得很烦,一般的做法就是不管三七二十一,在字符串前面加一个‘L’

    如调用函数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有关,没怎么用到过。

    LPSTR:即 char *,指向以'/0'结尾的8位(单字节)ANSI字符数组指针

    LPWSTR:即wchar_t *,指向'/0'结尾的16位(双字节)Unicode字符数组指针

    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、相互转换方法

    LPWSTR->LPTSTR:   W2T();
    LPTSTR->LPWSTR:   T2W();
    LPCWSTR->LPCSTR: W2CT();
    LPCSTR->LPCWSTR: T2CW();

    ANSI->UNICODE:     A2W();

    UNICODE->ANSI:     W2A();

    另外,CString转为CStringW方法(通过一个wchar_t数组来转)

     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、另外,还可以强行转换,不过不一定能成功

    5、还有_bstr_t ( 对BTSTR的封装,需要#include<comdef.h> ),也可将单字节字符数组指针转为双字节字符数组指针,还没怎么没用到过。

     

     

    ==========================================================

    DWORD本来被定义为unsigned long,DWORD的含义就是双字,一个字是2字节,双字就是32字节。  但是在C/C++中,经常会用到把一个指针转换成数字储存,然后再将其传唤为指针调用。那么在32位系统下,指针是32位长度的,在64位系统下,指针是64位长度的,所以微软引入了DWORD_PTR和INT_PTR等带_PTR的类型,这些类型是这么保证的:将指针转换成带_PTR的类型然后再转换回来,可以得到原始的指针,不会发生截断。在实现上,DWORD_PTR在32位程序和64位程序的定义是不同的,32位定位为unsigned long,64位定义为unsigend __int64。  基于这个要求,你最好使用C#提供的类似的功能: System.UIntPtr 这个数据类型对应C语言里面带_PTR的类型,保证程序在32位平台和64位平台,以及今后会出现的128位平台都可以正常运行。 
    1个二进制位称为1个bit,8个二进制位称为1个Byte,也就是1个字节(8位),2个字节就是1个Word(1个字,16位),则DWORD(DOUBLE WORD)就是双字的意思,两个字(32位)

    1.CString:动态的TCHAR数组。它是一个完全独立的类,封装了“+”等操作符和字符串操作方法,换句话说就是CString是对TCHAR操作的方法的集合。

    2.LPCTSTR:常量的TCHAR指针,其定义为

    1 typedef const TCHAR* LPCTSTR

    其中

         L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32位操作系统中, long指针和near指针及far修饰符都

           是为了兼容的作用。没有实际意义。

    P表示这是一个指针

    C表示是一个常量

    T表示在Win32环境中, 有一个_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环境中, 有一个_T宏 。

    4.WCHAR:WCHAR其实也是一个宏,表示的就是wchar_t,为了书写方便重新定义的一个宏而已,其定义为:

    1 typedef wchar_t WCHAR

    5.string:string是c++中的字符串变量,因为操作c类型的char非常麻烦,而且很容易出现内存泄漏,所以c++就对c中的char 进行了封装,其中

    1 包含了赋值、删除、增加等常用操作,这些操作都不用考虑内存,是的使用更加方便,所以能使用string就尽量使用string,使用string要包含其头文件:
    1 #include <string>
    1 注意不是:
    1 #include <string.h>

    因为string.h是C字符串头文件。

    string中常用的函数有:

    01 a) =,assign()   //赋以新值
    02 b) swap()   //交换两个字符串的内容
    03 c) +=,append(),push_back() //在尾部添加字符
    04 d) insert() //插入字符
    05 e) erase() //删除字符
    06 f) clear() //删除全部字符
    07 g) replace() //替换字符
    08 h) + //串联字符串
    09 i) ==,!=,<,<=,>,>=,compare()  //比较字符串
    10 j) size(),length()  //返回字符数量
    11 k) max_size() //返回字符的可能最大个数
    12 l) empty()  //判断字符串是否为空
    13 m) capacity() //返回重新分配之前的字符容量
    14 n) reserve() //保留一定量内存以容纳一定数量的字符
    15 o) [ ], at() //存取单一字符
    16 p) >>,getline() //从stream读取某值
    17 q) <<  //将谋值写入stream
    18 r) copy() //将某值赋值为一个C_string
    19 s) c_str() //将内容以C_string返回
    20 t) data() //将内容以字符数组形式返回
    21 u) substr() //返回某个子字符串
    22 v)查找函数
    23 w)begin() end() //提供类似STL的迭代器支持
    24 x) rbegin() rend() //逆向迭代器
    25 y) get_allocator() //返回配置器
    1   
    1 6.wchar_twchar_t是c++中用来表示宽字节的数据类型,即unicode编码的数据类型。
    1 7.charchar是c中的字符数据类型,属于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 既然有定义了这么多的数据类型,所以他们之间的相互转化是少不了的。
    1 A):CString的转化
    1 1.CString和LPCTSTR的转化:
    1 CString和LPCTSTR不需要转化,两者是等价的,所以:
    1 CString str("cstring");
    2 LPCTSTR pcStr = str;

    2.CString和LPTSTR的转化:

    下述转法虽然可以,但是却不安全:

    1 CString str("string");
    2 LPTSTR pStr = (LPTSTR)(LPCTSTR)(str);

    因为本来转化后的字符串变得可以修改了,造成了安全隐患。

    正确的转化方法为:

    1 CString str("string");
    2 LPTSTR pStr = str.GetBuffer();
    3 str.ReleaseBuffer();
    1 注意:GetBuffer()和ReleaseBuffer()之间不可以调用任何的CString函数,比如GetLength()函数,因为无法预测对内存的操作,所以任何CString函数得到的
    1 结果都是不确定的。
    1   

    3.CString和WCHAR*(wchar_t*)的转化

    方法一:使用wcscpy()函数

    1 CString str("string");
    2 WCHAR pWchar[100];
    3 wcscpy(pWchar,str);

    方法二:使用wcscpy_s()函数

    这个函数是上一个函数的安全版本,调用上一个函数如果pWchar的内存不足时,容易引发意味的错误,但是wcscpy_s()则不会,应该其内存大小已经指定出来了:

    1 CString str("string");
    2 WCHAR pWchar[100];
    3 wcscpy(pWchar,100,str);

    方法三:使用_tcscpy()函数

    1 CString str("string");
    2 WCHAR pStr[100];
    3 _tcscpy(pStr,str);

    方法四:使用_tcscpy_s()函数

    同wcscpy_s()一样,_tcscpy_s()函数也是_tcscpy()函数的安全版本:

    1 CString str("string");
    2 WCHAR pStr[100];
    3 _tcscpy_s(pStr,100,str);
    1   

    4.CString和char*的转化

    方法一:使用wcstombs()函数

    1 CString str("string");
    2 char pChar[100];
    3 wcstombs(pChar,str,100);

    方法二:使用wcstombs_s()函数

    同上面一样,wcstombs_s()是wcstombs()的安全版本:

    总结:

          上面一会使用strcpy(),一会使用wcscpy(),一会又使用_tcscpy(),这三者有什么关系呢,其实strcpy()处理的就是 ASCII编码的字符,像char,而wcscpy()处理的是Unicode 编码,_tcscpy()则是一个宏,如果你使用的是ASCII编码,那么_tcscpy()表示的就是strcpy(),如果你使用的是Unicode 编码,那么_tcscpy()表示的就是wcscpy(),这可以通过定义_UNICODE或UNICODE宏来实现。你可能已经知道了为什么要定义这么 一个宏,对!就是为了代码的移植。还有一个函数就是wcstombs(),这个函数是干什么用的呢?其实除了Unicode编码,还有一个编码,那就是多 字节编码,通常用的是双字节编码,vc就支持这种编码,函数wcstombs()就是为了实现多字节和单字节转换而设计的。

  • 相关阅读:
    POJ 1015 Jury Compromise【DP】
    POJ 1661 Help Jimmy【DP】
    HDU 1074 Doing Homework【状态压缩DP】
    HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
    占坑补题。。最近占的坑有点多。。。
    Codeforces 659F Polycarp and Hay【BFS】
    Codeforces 659E New Reform【DFS】
    Codeforces 659D Bicycle Race【计算几何】
    廖大python实战项目第四天
    廖大python实战项目第三天
  • 原文地址:https://www.cnblogs.com/zhwl/p/2758413.html
Copyright © 2011-2022 走看看