2015-03-13 133 views
3

我包括我的.cpp程序下列文件:C++字符串类型混淆

#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时,编译器会提示警告,说它已经被定义。那么问题是什么?为什么它选择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会提示已被定义的警告。

+0

根据[文档](https://msdn.microsoft.com/en-us/library/c426s321.aspx),控制宏是'_UNICODE',而不是'UNICODE'。你有这个定义正确吗? – Angew 2015-03-13 08:23:26

+0

是的,我试着在.cpp文件的开头定义'UNICODE'和/或'_UNICODE',但它没有帮助 – nicks 2015-03-13 08:25:10

+0

你有没有计划使用MBCS或SBCS?如果没有,你可以摆脱整个tchar业务并明确使用'wchar_t'。 – Angew 2015-03-13 08:30:09

回答

4

根据MSDN,_tcslen扩展到的是由宏_UNICODE控制。另一方面,LPCTSTRUNICODE控制。确保你有一致地定义这两个宏,并且在任何可能使用它们的头部被包含之前。

+0

请参阅定义unicode的编辑 – nicks 2015-03-13 08:31:15

+0

@NikaGamkrelidze您的VS项目设置(在项目属性中)是否还包含unicode? – Angew 2015-03-13 08:33:51

+0

'之前的任何标题'<<真的有把戏。包含后我正在定义_UNICODE。但为什么这是必要的?这些标题不应该自己定义它吗? – nicks 2015-03-13 08:35:20

2

_tcslen正在扩大到strlenLPCTSTR正在扩大到const wchar_t*。这意味着你有_UNICODEUNICODE定义不一致。前者由TCHAR头文件使用,后者由Windows头文件使用。鉴于您的更新问题,我会说你有UNICODE定义和_UNICODE未定义。

除此之外,你不应该使用TCHAR让你的生活变得更容易。当你需要为Win9x和WinNT编译单个源代码时,这很有用。如今,你大概不会针对Win9x。所以我的建议是简单地删除所有使用TCHAR,并让你的代码更简单。

+0

请参阅编辑实际代码 – nicks 2015-03-13 08:27:32