【问题标题】:Converting LPCSTR to LPCWSTR in C++, ATL not available在 C++ 中将 LPCSTR 转换为 LPCWSTR,ATL 不可用
【发布时间】:2021-12-17 17:24:26
【问题描述】:

在我开始之前,

请理解这个问题不是重复。有相同标题的问题:

将 LPCSTR 转换为 LPCWSTR

但是,在提出这个问题之前,我做了一些研究,发现了 ATLActive Template Library

但是我使用的编译器不附带 ATL,它不允许我从 LPCSTR 转换为 LPCWSTR

另外,要了解为什么我需要转换这两种数据类型,原因是我正在处理一个项目实际上是 一个控制台游戏引擎。

如果你不知道,要重命名控制台窗口,你需要使用SetConsoleTitle(LPCWSTR winName)

起初,我使用LPCWSTR 数据类型作为我的函数的参数。但是,当我尝试另一个函数,实际上是一个绘图函数时,会发生这种情况:

您在此处看到的UNICODE 字符组合是在控制台上绘制一个矩形的函数。矩形正确显示,但是,有一些 文本,或者我应该说,控制台标题本身,显示在矩形上。

我没有添加任何在矩形上显示控制台标题的东西,也没有以任何方式弄乱我的代码。我烧写了几次代码,没有任何问题,但是,不知何故,控制台标题显示在矩形上。

我不知何故认为这与 LPCWSTR 数据类型有关,因为当我尝试该功能时,SetConsoleTitle() 手动

帮我找到解决办法好吗?

【问题讨论】:

  • MultiByteToWideChar ?
  • SO 搜索中第一个也是投票最多的命中有一个不使用 ATL 的答案。 SetConsoleTitle 的参数类型取决于您是否为 unicode 构建。您可以显式使用SetConsoleTitleA 来使用窄字符串。
  • 您能否提供一个minimal reproducible example 来展示您的尝试?很难相信设置控制台标题会破坏代码的其他部分,除非您使用相同的变量并且代码中有一些不正确的地方。您最近评论的问题上的other answer 不使用 ATL,应该可以正常工作。
  • when I tried another function, which is actually a drawing function, this is what happens - 你应该发布代码,可能你在某处有未初始化的内存或缓冲区溢出,或者只是不小心不正确地重用了缓冲区。没有标准函数会故意将窗口标题添加到转换后的文本中。
  • 听起来您的程序中存在错误,您认为SetConsoleTitle 与它们有关的假设可能是错误的。

标签: c++ console lpcwstr lpcstr


【解决方案1】:

由于标题通常是不变的,你可以简单地调用

SetConsoleTitle(L"My Title"); //or
const wchar_t* title = L"My Title";
SetConsoleTitle(title);

一般情况下,使用MultiByteToWideChar 将 ANSI 或 UTF8 转换为 UTF16

#include <iostream>
#include <string>
#include <windows.h>

std::wstring u16(const char* in, int codepage)
{
    if (!in) return std::wstring(L"");
    int size = MultiByteToWideChar(codepage, 0, in, -1, NULL, 0);
    std::wstring ws(size, L'\0');
    MultiByteToWideChar(codepage, 0, in, -1, ws.data(), size);
    return ws;
}

int main()
{
    const char* str = "My Title"; //<- ANSI string
    SetConsoleTitle(u16(str, CP_ACP).c_str());
    std::string s;
    std::cin >> s;

    str = reinterpret_cast<const char*>(u8"Ελληνικά"); //<- UTF8
    SetConsoleTitle(u16(str, CP_UTF8).c_str());
    std::cin >> s;

    return 0;
}

请注意,程序退出时标题会变回。

【讨论】:

  • 这个答案很有帮助,但是,正如@molbdnilo 所说,我们可以使用SetConsoleTitleA(LPCSTR lpConsoleTitle),这也是另一个有用的解决方案。
猜你喜欢
  • 2011-12-24
  • 1970-01-01
  • 2013-11-05
  • 2012-07-26
  • 2011-11-13
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多