五.MFC 动态字符串类 CString
// …/Microsoft Visual Studio 8/VC/atlmfc/include/afx.h
一个CString 对象由可变长度的一队字符组成。CString 使用类似于Basic 的语法提供函数和操作符。连接和比较操作符以及简化的内存管理使CString 对象比普通字符串数组容易使用。
CString 是基于TCHAR 数据类型的对象。如果在你的程序中定义了符号_UNICODE ,则TCHAR 被定义为类型wchar_t ,即16 位字符类型;否则,TCHAR 被定义为char ,即8 位字符类型。在UNICODE 方式下,CString 对象由16 位字符组成。非UNICODE 方式下,CString 对象由8 位字符组成。 而VS2005 默认TCHAR 是wchar 而不是char.
当不使用_UNICODE 时,CString 是多字节字符集(MBCS ,也被认为是双字节字符集,DBCS )。注意,对于MBCS 字符串,CString 仍然基于8 位字符来计算,返回,以及处理字符串,并且你的应用程序必须自己解释MBCS 的开始和结束字节。
CString 提供 operator LPCTSTR 来在 CString 和 LPCTSTR 之间进行转换。
有关CString 的操作请参考MSDN MFC 类库。
六. 更安全的 C 语言字符串处理函数 Strsafe.h
// …/Microsoft Visual Studio 8/VC/PlatformSDK/Include/strsafe.h
注意:使用 StringCchCopy /StringCchPrintf 时要#include "strsafe.h".
STRSAFEAPI 是为了解决现有的 C 语言运行时函数的代码太容易产生的 “ 内存溢出 ” 问题。当我们引用 strsafe 系列函数时,原有的 C 语言字符串处理函数都将被自动进行 #undef 处理。调试过程中的警告或出错信息将会告诉我们哪些函数哪些不安全,哪些已经被相应的 strsafe 系列函数取代了。
//1. 不赞成使用不安全的函数,以避免产生编译错误
//2. 如果你不要安全处理,你可以在包含strsafe.h 头文件之前,
#define STRSAFE_NO_DEPRECATE
#ifdef DEPRECATE_SUPPORTED
// First all the names that are a/w variants (or shouldn't be #defined by now anyway).
#pragma deprecated(strcpy)
#pragma deprecated(wcscpy)
#pragma deprecated(lstrcpy)
#pragma deprecated(StrCpy)
类似的Strcat/wcscat/lstrcat/StrCat ,sprintf/wsprintf
以下是D3D 中预编译头文件dxstdafx.h
#pragma warning ( disable : 4996 ) // 将报警置为无效
#include <strsafe.h>
#pragma warning ( default : 4996 ) // 将报警置为默认
有关 #pragma warning 请参考: http://hi.baidu.com/iceland9/blog/item/5af9c0bfd334de0a18d81f33.html
以下是D3D 从VS2003 移植到VS2005 时遇到的安全警告:
warning C4996: 'wcscpy' was declared deprecated
see declaration of 'wcscpy'
Message: 'This function or variable may be unsafe.
Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
warning C4995: 'lstrcpy': name was marked as #pragma deprecated
warning C4995: 'wsprintf': name was marked as #pragma deprecated
推荐使用新的安全可靠的 TRSAFEAPI :
STRSAFEAPI
StringCchCopyA(
__out_ecount(cchDest) STRSAFE_LPSTR pszDest,
__in size_t cchDest,
__in STRSAFE_LPCSTR pszSrc);
STRSAFEAPI
StringCchCopyW(
__out_ecount(cchDest) STRSAFE_LPWSTR pszDest,
__in size_t cchDest,
__in STRSAFE_LPCWSTR pszSrc);
#ifdef UNICODE
#define StringCchCopy StringCchCopyW (W 为 Wide Unicode)
#else
#define StringCchCopy StringCchCopyA (A 为 ANSI)
#endif // !UNICODE
#undef strcpy
#define strcpy strcpy_instead_use_StringCbCopyA _or_StringCchCopyA ;
#undef wcscpy
#define wcscpy wcscpy_instead_use_StringCbCopyW _or_StringCchCopyW ;
#undef wsprintf
#define wsprintf wsprintf_instead_use_StringCbPrintf _or_StringCchPrintf;
// Then all the windows.h names - we need to undef and redef based on UNICODE setting
#undef lstrcpy // 取消已定义的宏
#pragma deprecated(lstrcpy) // 安全警告
#ifdef UNICODE // 使用 UNICODE 编程
#define lstrcpy lstrcpyW // 重定义
#else
#define lstrcpy lstrcpyA // 重定义
#endif
类似的有对lstrcat/wsprintf/wvsprintf 的#undef ,#pragma deprecated ,#define 。
推荐使用新的安全可靠的 TRSAFEAPI :
#undef lstrcpy
#define lstrcpy lstrcpy_instead_use_StringCbCopy _or_StringCchCopy ;
// Then the shlwapi names - they key off UNICODE also.
#undef StrCpy
#pragma deprecated(StrCpy)
#ifdef UNICODE
#define StrCpy StrCpyW
#else
#define StrCpy lstrcpyA
#endif
类似的有#undef StrCpyA /StrCpy /StrCatA /StrCat /StrNCat /StrCatN
以及对StrCpy/StrCat/StrNCat 的#undef ,#pragma deprecated ,#define 。
推荐使用新的安全可靠的 TRSAFEAPI :
#undef StrCpy
#define StrCpy StrCpy_instead_use_StringCbCopy _or_StringCchCopy ;
// Then all the CRT names - we need to undef/redef based on _UNICODE value.