• 《转》c++ 字符串系列:字符编码进阶(下)


    .使用TCHAR

    TCHAR是一种字符串类型,它让你在以MBCS和UNNICODE来build程序时可以使用同样的代码,不需要使用繁琐的宏定义来包含你的代码。TCHAR的定义如下:

    #ifdef UNICODE

    typedef wchar_t TCHAR;

    #else

    typedef char TCHAR;

    #endif

    所以用MBCS来build时,TCHAR是char,使用UNICODE时,TCHAR是wchar_t。还有一个宏来处理定义Unicode字符串常量时所需的L前缀。

    #ifdef UNICODE

    #define _T(x) L##x

    #else

    #define _T(x) x

    #endif

    ##是一个预处理操作符,它可以把两个参数在一起。如果你的代码中需要字符串常量,在它前面加上_T宏。如果你使用Unicode来build,它会在字符串常量前加上L前缀。像是用宏来隐藏SetWindowTextA/W的细节一样,还有很多可以供你使用的宏来实现str***()和_mbs***()等字符串函数。例如,你可以使用_tcsrchr宏来替换strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根据你预定义的宏是_MBCS还是UNICODE来扩展成正确的函数,就像SetWindowText所作的一样。

      不仅str***()函数有TCHAR宏。其他的函数如, _stprintf(代替sprinft()和swprintf()),_tfopen(代替fopen()和_wfopen())。 MSDN中"Generic-Text Routine Mappings."标题下有完整的宏列表。

    .字符串宏定义

    由于Win32 API文档的函数列表使用函数的常用名字(例如,"SetWindowText"),所有的字符串都是用TCHAR来定义的。(除了XP中引入的只适用于Unicode的API)。下面列出一些常用的typedefs,你可以在MSDN中看到他们。

    type

    Meaning in MBCS builds

    Meaning in Unicode builds

    LPSTR

    char* char *

    LPCSTR

    const char* const char*

    WCHAR

    wchar_t wchar_t

    LPWSTR

    wchar_t* wchar_t*

    LPCWSTR

    const wchar_t* const wchar_t*

    TCHAR

    char wchar_t

    LPTSTR

    TCHAR* TCHAR*

    LPCTSTR

    const TCHAR* const TCHAR*

    一个增加的字符类型是OLETYPE。它表示自动化接口(如word提供的可以使你操作文档的接口)中使用的字符类型。这种类型一般被定义成wchar_t,然而如果你定义了OLE2ANSI预处理标记,OLECHAR将会被定义成char类型。我知道现在已经没有理由定义OLE2ANSI(从MFC3以后,微软已经不使用它了),所以从现在起我将把OLECHAR当作Unicode字符。

    这里给出你将会看到的一些OLECHAR相关的typedefs:

    type meaning

    OLECHAR

    Unicode character (wchar_t)

    LPOLESTR

    string of OLECHAR (OLECHAR*)

    LPCOLESTR

    constant string of OLECHAR (const OLECHAR*)

    还有两个用于字符串和字符常量的宏定义,它们可以使同样的代码被用于MBCS和Unicode builds:

    type meaning
    _T

    Prepends L to the literal in Unicode builds.

    OLESTR(x)

    Prepends L to the literal to make it an LPCOLESTR.

    在文档或例程中,你还会看到好多_T的变体。有四个等价的宏定义,它们是TEXT, _TEXT, __TEXT和__T,它们都起同样的做用。

    七.字符串扩展类型及封装类

    字符串的种类多种多样,有些可以应用在很多场合(比如C字符串的基础char类型),也有一些可能只是在特定情况下才会使用(比如使用MFC一般会用到CString,而开发COM组件一般会涉及到BSTR或CComBSTR)。希望通过下面的总结能让大家清楚地了解到各种不同类型字符串的出处和通常情况下的使用场合。

    封闭类 出处 功能简介 使用
    BSTR COM 特殊的字符串类型可以保存字符串长度 需要调用专门的API函数,容易造成内存泄漏。建议使用封闭类,比如CComBSTR.
    VARIANT COM 特殊结构,被设计用来实现跨语言的特性 用来在无类型语言如(Jscript和VBScript)来传递数据
    CString MFC 封闭TCHAR类型字符串 MFC中使用
    ColVariant MFC 继承自VARIANT 很少用
    _bstr_t CRT 是一纣BSTR的完整封闭类,隐藏了底层的BSTR  
    _variant_t CRT 是一个对VARIANT 的完整封闭,隐藏了底层的VARIANT  
    basic_string STL 类模板 string wstring
    CComBSTR ATL BSTR的封闭类,可直接讯问底层BSTR 在某些情况下比_bstr_t有用的多
    CComVariant ATl

    VARIANT的封装类,但是VARIANT没有被隐藏。

     
    CString

    WTL

    行为和MFC的 CString完全一样。

     
    System::String

    CLR 和 VC 7 类

    一个String对象包含一个不可改变的字符串序列。

     

    常用字符串转换

    1、函数 WideCharToMultiByte(),转换 UNICODE 到 MBCS。使用范例:

    LPCOLESTR lpw = L"Hello,你好";

    size_t wLen = wcslen( lpw ) + 1;  // 宽字符字符长度,+1表示包含字符串结束符

    int aLen=WideCharToMultiByte(  // 第一次调用,计算所需 MBCS 字符串字节长度

    CP_ACP,

    0,

    lpw,  // 宽字符串指针

    wLen, // 字符长度

    NULL,

    0,  // 参数0表示计算转换后的字符空间

    NULL,

    NULL);

    LPSTR lpa = new char [aLen];

    WideCharToMultiByte(

    CP_ACP,

    0,

    lpw,

    wLen,

    lpa,  // 转换后的字符串指针

    aLen, // 给出空间大小

    NULL,

    NULL);

    // 此时,lpa 中保存着转换后的 MBCS 字符串

    ... ... ... ...

    delete [] lpa;

    2、函数 MultiByteToWideChar(),转换 MBCS 到 UNICODE。使用范例:

    LPCSTR lpa = "Hello,你好";

    size_t aLen = strlen( lpa ) + 1;

    int wLen = MultiByteToWideChar(

    CP_ACP,

    0,

    lpa,

    aLen,

    NULL,

    0);

    LPOLESTR lpw = new WCHAR [wLen];

    MultiByteToWideChar(

    CP_ACP,

    0,

    lpa,

    aLen,

    lpw,

    wLen);

    ... ... ... ...

    delete [] lpw;

    3、使用 ATL 提供的转换宏。

    A2BSTR OLE2A T2A W2A

    A2COLE OLE2BSTR T2BSTR W2BSTR

    A2CT OLE2CA T2CA W2CA

    A2CW OLE2CT T2COLE W2COLE

    A2OLE OLE2CW T2CW W2CT

    A2T OLE2T T2OLE W2OLE

    A2W OLE2W T2W W2T

    上表中的宏函数,其实非常容易记忆:

    2

    好搞笑的缩写,to 的发音和 2 一样,所以借用来表示“转换为、转换到”的含义。

    A

    ANSI 字符串,也就是 MBCS。

    W、OLE

    宽字符串,也就是 UNICODE。

    T

    中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A

    C

    const 的缩写

    使用范例:

    #include <atlconv.h>

    void fun()

    {

    USES_CONVERSION;  // 只需要调用一次,就可以在函数中进行多次转换

    LPCTSTR lp = OLE2CT( L"Hello,你好") );

    ... ... ... ...

    // 不用显式释放 lp 的内存,因为

    // 由于 ATL 转换宏使用栈作为临时空间,函数结束后会自动释放栈空间。

    }

      使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:

    1、只适合于进行短字符串的转换;
    2、不要试图在一个次数比较多的循环体内进行转换;
    3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
    4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();

    本人新博客网址为:http://www.hizds.com
    本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232
  • 相关阅读:
    xml转义字符在mybatis动态sql中的使用
    jdbc类型与java类型
    aop日志(记录方法调用日志)
    mysql数据库关联查询【lert join】常见使用
    maven项目基本配置
    mapper文件的参数传入与获取
    idea新建项目出现push rejected如何解决
    快速从2个List集合中找出相同/不同元素
    Windows 环境下安装RocketMQ
    RabbitMQ java客户端集成 Spring 开发环境
  • 原文地址:https://www.cnblogs.com/zhangdongsheng/p/2299979.html
Copyright © 2020-2023  润新知