• VC++中关于TCHAR,WCHAR,LPSTR,LPWSTR,LPCTSTR的解释
    时间:2012-03-11   作者:佚名   出处:互联网

    许多VC++ 程序员对于像TCHAR,LPCTSTR这样诡异的标识符感到非常迷惑。今天,我将尝试简短的把这团迷雾解释清楚。

    一般来说,一个字符(character)占用1字节或是2字节,我们说1字节的字符是ANSI,他可以用来表示英语字母,而2字节的我们称之为Unicode,可以表示世界上所有的语言。。
    VC++使用char和wchar_t的内置数据类型来分别作为表示ANSI和Unicode字符。
    如果你想让你的C/C++程序是字符集无关的,该怎么做呢?
    如果你用通常的字符集来写,你可能会写成这样的。

    char cResponse; // 'Y' or 'N'
    char sUsername[64];
    // str* functions


    和这样的

    wchar_t cResponse; // 'Y' or 'N'
    wchar_t sUsername[64];
    // wcs* functions


    而现在,你可以简单的这样写。

    #include<TCHAR.H> // Implicit or explicit include
    TCHAR cResponse; // 'Y' or 'N'
    TCHAR sUsername[64];
    // _tcs* functions


    从此,当你的项目被作为Unicode编译的时候,TCHAR将会被转换成wchar_t,如果是被作为ANSI/MBCS来编译,则会自动转换成char,

    同样的,比起使用strcpy, strlen, strcat(也包含以_s结尾的安全版本)或者wcscpy, wcslen,wcscat(安全版本也可),你可以简单的使用_tcscpy,_tcslen, _tcscat 这些函数。

    当你表示硬编码的string时,你可以使用

    "ANSI String"; // ANSI
    L"Unicode String"; // Unicode

    _T("Either string, depending on compilation"); // ANSI or Unicode
    // or use TEXT macro, if you need more readability.


    没有前缀的string是ANSI string,有L前缀的是Unicode,而又_T或者TEXT指定的string则二者皆可,取决于编译器。

    String类,像MFC/ATL的CString类使用宏实现了两个版本,CStringA是ANSI,CStringW是为Unicode,当你使用CString(一个宏/typedef)的时候,会被自动转换成两个类中的一个

    ok,TCHAR是一个单字符,你就可以清晰的定义一个TCHAR数组,当你想表示一个字符指针或const字符指针的时候,你会使用下面三个中的哪个呢?

    // ANSI characters
    foo_ansi(char*);
    foo_ansi(const char*);
    /*const*/ char* pString;
     
    // Unicode/wide-string
    foo_uni(WCHAR*); // or wchar_t*
    foo_uni(const WCHAR*);
    /*const*/ WCHAR* pString;
     
    // Independent
    foo_char(TCHAR*);
    foo_char(const TCHAR*);
    /*const*/ TCHAR* pString;


    当读完一些关于TCHAR的内容的时候,你应该会选择一个正确的,但是,事实上,还有更好的选择,在那之前,注意TCHAR.H头文件仅仅生命了TCHAR类型,而为了使用下面的类型,你需要
    吧Windows.h包含进去。

    注意:如果你的项目已经隐式或是显式地包含了Windows.h那就不必包含了。

    char* 替换: LPSTR
    const char* 替换: LPCSTR
    WCHAR* 替换: LPWSTR
    const WCHAR* 替换: LPCWSTR (C在W之前, 因为 const 在 WCHAR之前)
    TCHAR* 替换: LPTSTR
    const TCHAR* 替换: LPCTSTR

    现在,希望你可以理解下面的函数原型

    BOOL SetCurrentDirectory( LPCTSTR lpPathName );
    DWORD GetCurrentDirectory(DWORD nBufferLength,LPTSTR lpBuffer);


    继续,你一定见过一些函数/方法让你传递字符集的大小,或者返回它的大小,比如GetCurrentDirectory函数,需要传递字符的数目而不是字节的数目举个例子

    TCHAR sCurrentDir[255];
    // Pass 255 and not 255*2
    GetCurrentDirectory(sCurrentDir, 255);


    另一方面,如果你需要分配字符的数目,你比如分配适当大小的字节,在C++中,你可以简单的使用new方法:

    LPTSTR pBuffer; // TCHAR*
    pBuffer = new TCHAR[128]; // Allocates 128 or 256 BYTES, depending on compilation.


    但是,你如果你使用内存分配函数像malloc,LocalAlloc, GlobalAlloc, 等,你必须指定字节数。

    pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );


    对返回值进行一次类型转换是必需的,如你所知,在malloc的参数中,确定了分配字节的大小,并在内存中开辟相应的空间。

    网友留言/评论

    我要留言/评论

    相关文章

    如何获取某个进程的主窗口以及创建进程的程序名?:在编写工具程序以及系统管理程序的时候。常常需要获取某个进程的主窗口以及创建此进程的程序名。获取主窗口的目的是向窗口发送各种消息。获取启动进程的程序名可以控制对进程的操作。但是有些进程往往有多个主窗口。你要的是哪一个主窗口呢?如果你用过Outlook程序,你就会发现它有多个主窗口,一个窗口列出收件箱和其它文件夹。如果你打开e-mail,便会有另外一个窗口显示信息。它们都是没有父窗口(或者说宿主窗口)的主窗口。运行一下Spy程序,你甚至会发现它们的窗口类名都相同:rctrl_renwnd32。资源管理器(Explorer.exe)也有不止一个主窗口。如图一所示,资源管理器有两个主窗口。一般来讲,想要获取主窗口,凭窗口的式样或类名,你没有什么办法知道哪一个窗口是真正意义上的主窗口。
    WINDOWS干干净净杀死进程编程:最近在写程序时碰到这样一个问题:我想将文件备份到网络驱动器上,但是有一些文件正在被其它程序使用,处于打开状态,而且是被独占打开,这时是没法对文件进行备份操作的。因此,要想备份这些文件,必须将打开它们的那些进程kill掉。那么如何干净地杀死这些打开文件的进程呢?相信看完本文后,自然会有办法解决!