C++字符串类型混淆
c++ string types confusion
我在我的 .cpp 程序中包含以下文件:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
然而,当我写
LPCTSTR pMsg;
DWORD msgLen;
...
msgLen = _tcslen(pMsg);
编译器提示如下错误:
C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from
'LPCTSTR' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast
当然,我可以通过转换为 LPCSTR
或使用 wcslen
轻松解决问题。但那是不对的,编译器不应该根据宏 UNICODE
自己决定所有这些东西吗?肯定是定义好了,因为我在文件开头写#define UNICODE
的时候,编译器提示warning,说已经定义了。那问题是什么?为什么它选择 strlen
而不是 wcslen
?
这里是实际的代码:
BOOL PrintString(HANDLE hOut, ...)
{
DWORD msgLen, count;
LPCTSTR pMsg;
va_list pMsgList;
va_start(pMsgList, hOut);
while((pMsg = va_arg(pMsgList, LPCTSTR)) != NULL)
{
msgLen = _tcslen(pMsg);
if(!WriteConsole(hOut, pMsg, msgLen, &count, NULL) && !WriteFile(hOut, pMsg, msgLen*sizeof(TCHAR), &count, NULL))
{
va_end(pMsgList);
return FALSE;
}
}
va_end(pMsgList);
return TRUE;
}
我都试过了,#define _UNICODE
和 #define _UNICODE
但都没有用。而且,#define _UNICODE
提示已经定义的警告
_tcslen
正在扩展到 strlen
。 LPCTSTR
正在扩展到 const wchar_t*
。这意味着您对 _UNICODE
和 UNICODE
的定义不一致。前者被TCHAR
头文件使用,后者被Windows头文件使用。鉴于您更新的问题,我会说您已定义 UNICODE
而 _UNICODE
未定义。
除此之外,您应该不使用 TCHAR
让您的生活更轻松。当您需要能够为 Win9x 和 WinNT 编译单个源代码时,这很有用。现在你可能不以 Win9x 为目标。所以我的建议是简单地删除所有 TCHAR
的使用,让你的代码更简单。
根据 MSDN,_tcslen
扩展到的内容由宏 _UNICODE
. LPCTSTR
, on the other hand, is controlled by UNICODE
控制。确保你有一致定义的这两个宏,并且在包含任何可能使用它们的 header 之前。
我在我的 .cpp 程序中包含以下文件:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
然而,当我写
LPCTSTR pMsg;
DWORD msgLen;
...
msgLen = _tcslen(pMsg);
编译器提示如下错误:
C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from 'LPCTSTR' to 'const char *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
当然,我可以通过转换为 LPCSTR
或使用 wcslen
轻松解决问题。但那是不对的,编译器不应该根据宏 UNICODE
自己决定所有这些东西吗?肯定是定义好了,因为我在文件开头写#define UNICODE
的时候,编译器提示warning,说已经定义了。那问题是什么?为什么它选择 strlen
而不是 wcslen
?
这里是实际的代码:
BOOL PrintString(HANDLE hOut, ...)
{
DWORD msgLen, count;
LPCTSTR pMsg;
va_list pMsgList;
va_start(pMsgList, hOut);
while((pMsg = va_arg(pMsgList, LPCTSTR)) != NULL)
{
msgLen = _tcslen(pMsg);
if(!WriteConsole(hOut, pMsg, msgLen, &count, NULL) && !WriteFile(hOut, pMsg, msgLen*sizeof(TCHAR), &count, NULL))
{
va_end(pMsgList);
return FALSE;
}
}
va_end(pMsgList);
return TRUE;
}
我都试过了,#define _UNICODE
和 #define _UNICODE
但都没有用。而且,#define _UNICODE
提示已经定义的警告
_tcslen
正在扩展到 strlen
。 LPCTSTR
正在扩展到 const wchar_t*
。这意味着您对 _UNICODE
和 UNICODE
的定义不一致。前者被TCHAR
头文件使用,后者被Windows头文件使用。鉴于您更新的问题,我会说您已定义 UNICODE
而 _UNICODE
未定义。
除此之外,您应该不使用 TCHAR
让您的生活更轻松。当您需要能够为 Win9x 和 WinNT 编译单个源代码时,这很有用。现在你可能不以 Win9x 为目标。所以我的建议是简单地删除所有 TCHAR
的使用,让你的代码更简单。
根据 MSDN,_tcslen
扩展到的内容由宏 _UNICODE
. LPCTSTR
, on the other hand, is controlled by UNICODE
控制。确保你有一致定义的这两个宏,并且在包含任何可能使用它们的 header 之前。