问题
无论出于什么原因你都不可能避免接触到UNICODE和其它的字符编码,比如不同系统API调用、其他函数库的引入、COM等等。所以在编写Windows(或其他)程序时运用一点点技巧无疑会减少很多不必要的麻烦。在调用涉及字符操作的API时你可能会遇到下面问题:
- 函数调用需要wchar_t*或者char*字符参数。
- 函数无法导入XXX(wchar_t*,...)——通常引用第三方库时,应用程序与库的编码不一致引起的。我曾经在使用ACE时遇到过类似的问题,VS2005的默认工程属性编码为UNICODE,而ACE不是,这导致的结果是我无法导入任何参数包含字符的函数。
- 非UNICODE平台代码要在UNICODE编码平台上运行。
解决
<tchar.h>定义了_TCHAR、_T、__T、_TEXT;<winnt.h>定义了等价的宏TCHAR、TEXT、__TEXT。<tchar.h>是C++编译器自带头文件,对平台依赖性要小的多。然而对于一个特定范围的平台(如:Windows系列),使用系统预定义宏是建立最优文本处理方案的选择。
字符操作总是使用_tcscat 、_tcschr、_tcscpy、_tcscpy_s、_tcscspn 、_tcslen、 _tcsnlen 、_tcsncat 等宏。
建议使用
<strsafe.h>,无论是编程或者对于面试(曾经被要求写出strcpy实现,人家说我编码风格不好,缺少太多的检查,实际上该函数本身的缺陷导致做在多的检查也无济于是的。why?很多关于内存溢出的问题都是它惹的^_^)来讲都是个好选择。示例代码中有关于这些函数的使用,查下帮助尽量使用这些函数,将它做为一种习惯。
在编译期通过改变预定义宏——添加或删除_UNICODE、UNICODE宏定义而改变整个工程的字符编码。
示例
#include
<
strsafe.h
>
int GetName(TCHAR * lpszName)
{
const _TCHAR szName[] = _T( "god " );
size_t size = 0 ;
StringCchLength(szName, 1024 , & size); // from strsafe.h
StringCchCopy(lpszName, size, szName); // from strsafe.h
return 0 ;
}
int main( int argc, _TCHAR * argv[])
{
TCHAR szName[ 128 ] = { 0 };
GetName(szName);
return 0 ;
}
int GetName(TCHAR * lpszName)
{
const _TCHAR szName[] = _T( "god " );
size_t size = 0 ;
StringCchLength(szName, 1024 , & size); // from strsafe.h
StringCchCopy(lpszName, size, szName); // from strsafe.h
return 0 ;
}
int main( int argc, _TCHAR * argv[])
{
TCHAR szName[ 128 ] = { 0 };
GetName(szName);
return 0 ;
}