C++字符串类型混淆

3

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


根据文档所述,控制宏是_UNICODE而不是UNICODE。您是否正确定义了它? - Angew is no longer proud of SO
是的,我尝试在.cpp文件开头定义UNICODE和/或_UNICODE,但没有帮助。 - nicks
你有计划使用MBCS或SBCS吗?如果没有,你可以直接摆脱整个tchar业务并显式使用'wchar_t'。 - Angew is no longer proud of SO
2个回答

4
根据MSDN的说明,_tcslen扩展到的内容由宏_UNICODE控制。而另一方面,LPCTSTRUNICODE控制。请确保这两个宏定义一致,并在包含任何可能使用它们的头文件之前定义。

2
@Nika 简单地停止使用 tchar,你的所有问题就都解决了。 - David Heffernan
1
@NikaGamkrelidze 他们怎么能这样?? 这个宏的目的是让您选择是否要使用SBCS、MBCS或UTF-16。头文件查看控制宏的状态,并相应地定义typedef和函数宏。 - Angew is no longer proud of SO
@David,您建议明确使用宽字符及其相关函数吗? - nicks
1
非常简单。去掉TCHAR。对类型明确表示。因此使用wchar_t。定义“UNICODE”。结束了。这是我的答案建议。 - David Heffernan
1
@NikaGamkrelidze 虽然该文档的主要目的略有不同,但您可能想阅读UTF-8 everywhere,或者至少阅读“如何在Windows上处理文本”一节。 - Angew is no longer proud of SO
显示剩余7条评论

2
_tcslen正在扩展为strlen。LPCTSTR正在扩展为const wchar_t*。这意味着您的_UNICODE和UNICODE定义不一致。前者由TCHAR头文件使用,后者由Windows头文件使用。根据您更新的问题,我认为您已经定义了UNICODE并且未定义了_UNICODE。
除此之外,如果您不再针对Win9x,则应通过不使用TCHAR来简化代码,这将使您的生活更加轻松。在需要能够为Win9x和WinNT编译单个源代码时,使用TCHAR很有用。现在您可能不再针对Win9x,所以我的建议是简单地删除所有对TCHAR的使用,从而使代码更加简单。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接