【TCHAR、_T与_TEXT】【strcpy、wcscpy与_tcscpy】(转)

瘦欲@ 提交于 2019-12-15 04:57:47

https://blog.csdn.net/lu_chaoqun/article/details/19208105

 

(内容出自《把脉VC++》,挺好的一本书,下面内容是我整理摘录的两小节,顺便吐槽微软还真是整天把C搞的多复杂,让人找来找去)

4.5.3  TCHAR、_T与_TEXT

计算机最初使用的不是UNICODE,最初的系统和程序都采用的是ANSI或者MBCS,那么,问题来了:我们开发程序的时候,是采用char还是wchar_t?观察如下代码:

char msg[] = "学习C++"; 
当我们准备采用wchar_t时,则需要改成:

wchar_t msg[] = L"学习C++"; 
太麻烦了!幸运的是,Visual C++的开发者预知到了这样的麻烦,他们从而为此造出了一批宏,这些宏看起来乱七八糟的,但是确实解决了我们的问题,且看一段代码:


TCHAR msg[] = _T("学习C++"); 
这段代码中,msg到底是char数组还是wchar_t数组呢?Visual C++的解释是,如果需要它是char数组,那么它就是char数组;否则,它就是wchar_t数组。这样的魅力来源于宏TCHAR的定义:

typedef   unsigned   char   CHAR;  
typedef   unsigned   wchar_t   WCHAR;   
 
#ifdef   UNICODE  
    typedef   wchar_t   TCHAR;   
#else  
    typedef   unsigned   char   TCHAR;  
#endif
由此可以看出,CHAR实际上就是unsigned char,WCHAR为wchar_t,而TCHAR根据是否支持UNICODE而不同。宏UNICODE由此变得尤其重要,当我们定义了UNICODE宏,就相当于告诉了编译器:我准备采用UNICODE版本。这个时候,TCHAR就会摇身一变,由unsigned char变成了wchar_t。

Visual C++项目属性中都包含一项字符集的设置,如图4-14所示。很容易理解,它与宏UNICODE之间存在着某种关系(还有宏MCBS,为了简化讨论,在此省略)。

 
(点击查看大图)图4-14  在Visual C++中设置项目采用的字符集
前面分析了TCHAR,接下来再来看看_T的含义:

#define _T(x)       __T(x)  
#define _TEXT(x)    __T(x)  
 
#ifdef   UNICODE  
    #define __T(x)      L ## x  
#else  
    #define __T(x)      x  
#endif 

同理,当UNICODE宏被定义,"_T("学习C++")"会解释成"L"学习C++"",否则它只将其解释成""学习C++""。

因此,我们建议这样书写代码:

TCHAR msg[] = _T("学习C++"); 
除TCHAR之外,Windows还定义了一系列的包含T的宏:


#ifdef  UNICODE   
    typedef WCHAR TCHAR, * PTCHAR ;  
    typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;   
    typedef LPCWSTR LPCTSTR ;        
#else  
    typedef char TCHAR, * PTCHAR ;    
    typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;   
    typedef LPCSTR LPCTSTR ;     
#endif

 
4.5.4  strcpy、wcscpy与_tcscpy

C++标准库函数提供了字符和字符串的操作函数,并提供了其UNICODE版本,如:

char *strcpy(char *strDestination, const char *strSource);  
wchar_t *wcscpy(wchar_t *strDestination, const wchar_t *strSource); 

wcscpy()即为strcpy()的宽字符版本,与_T类似的,Visual C++提供了类似的同名函数:

#ifdef  UNICODE   
    #define _tcscpy     wcscpy  
#else  
    #define _tcscpy     strcpy  
#endif 

因此我们建议这样书写代码:

TCHAR src[] = _T("学习C++");  
TCHAR dest[20];  
_tcscpy(dest, src); 

比如,在使用printf()的时候,我会尝试使用_tprintf()。

同样的版本问题一样会困扰着main()函数:

main( int argc, char *argv[ ], char *envp[ ]);  
wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ]); 

再来看_tmain()的定义:

#ifdef  UNICODE   
    #define _tmain      wmain  
    #define _tWinMain   wWinMain  
#else  
    #define _tmain      main  
    #define _tWinMain   WinMain  
#endif 

这就是为什么Win32控制台项目默认输出,提供一个_tmain()函数的缘故。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!