[英]Printing wchar_t to console in C++
我制作了一个简单的程序,它将读取 PS1 存储卡二进制文件,并在 Visual Studio 中使用 C++ 在控制台中显示其内容。 游戏标题在内存中以 Shift-JIS 格式编码,所以我使用 MultiByteToWideChar 函数来转换它们:
// Converting Shift-JIS
char lTitle[65];
strcpy_s(lTitle, mymemcard[lFrame - 1].title);
int lTitleChars = MultiByteToWideChar(932, 0, lTitle, -1, NULL, 0);
wchar_t* lTitleL = new wchar_t[lTitleChars];
MultiByteToWideChar(932, 0, lTitle, -1, lTitleL, lTitleChars);
我现在的问题是我无法将 lTitleL 变量打印到控制台。 我试过 cout、wcout、printf、wprintf,我无法让它们工作! 我知道 lTitleL 变量正确地保存了标题,因为我可以在调试器中看到它。 当我调用我尝试过的任何打印函数时,根本没有打印任何内容。 任何帮助,将不胜感激! 谢谢。
大编辑:
好的,这就是我的情况:
// Converting Shift-JIS to UTF-8 //
///////////////////////////////////
// First, convert the multi-byte Shift-JIS format into wide characters
strcpy_s(lTitle, mymemcard[lFrame - 1].titleMB);
lTitleChars = MultiByteToWideChar(932, 0, lTitle, -1, NULL, 0);
wchar_t* lTitleFW = new wchar_t[lTitleChars];
MultiByteToWideChar(932, 0, lTitle, -1, lTitleFW, lTitleChars);
wprintf(L"FW, WriteConsoleW - ");
WriteConsoleW(consoleHandle, lTitleFW, lTitleChars, NULL, 0);
wprintf(L"\n");
// Memory card seems to store all characters in their "Full Width" forms, we need to convert them to Half-Width so they display nicely in the console
wchar_t* lTitleHW = new wchar_t[lTitleChars];
LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_HALFWIDTH, lTitleFW, lTitleChars, lTitleHW, lTitleChars, NULL, NULL, 0);
wprintf(L"HW, WriteConsoleW - ");
WriteConsoleW(consoleHandle, lTitleHW, lTitleChars, NULL, 0);
wprintf(L"\n");
wprintf(L"HW, wprintf() - %s\n", lTitleHW);
// Now we can convert it into UTF-8 format to allow it to be printed using std::cout
// This step isn't necessary as we could call WriteConsoleW on lTitleHW instead, but why not
lTitleChars = WideCharToMultiByte(CP_UTF8, 0, lTitleHW, -1, NULL, 0, NULL, NULL);
char* lTitleUTF = new char[lTitleChars];
WideCharToMultiByte(CP_UTF8, 0, lTitleHW, -1, lTitleUTF, lTitleChars, NULL, NULL);
strcpy_s(mymemcard[lFrame - 1].titleUTF, lTitleUTF);
wprintf(L"UTF, wprintf() - %S\n\n", lTitleUTF);
delete[] lTitleFW;
delete[] lTitleHW;
delete[] lTitleUTF;
///////////////////////////////////
为了帮助可视化输出,以下是使用 NSimSun 字体的控制台屏幕截图:
在这里使用 Consolas 字体:
现在我的问题是:我不是特别喜欢 NSimSun 字体,是否还有其他字体看起来更像 Consolas 字体,它们确实包含全/半宽日语字符的所有字形? 如果是这样,我如何将它们打包到我的控制台应用程序中以使其可移植?
谢谢!
Windows 对在控制台上打印 Unicode 的支持有限。 使用MessageBoxW(0, lTitleL, 0, 0)
测试您的转换,只要转换正常,就可以保证成功。
要打印到控制台窗口,您必须调用_setmode(_fileno(stdout), _O_U16TEXT);
为了打印超出 ASCII 范围的字符。
坚持使用std::wcout
或wprintf(L"%s", str)
如果控制台不支持正确的字体,还有一个问题。 你必须尝试不同的字体。 请参阅下面的示例。 还可以考虑使用具有自动清理功能的std::wstring
。
#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>
#include <Windows.h>
int main()
{
const wchar_t *src = L"ABC 日本語";
int size;
size = WideCharToMultiByte(932, 0, src, -1, NULL, 0, 0, 0);
std::string temp(size, 0);
WideCharToMultiByte(932, 0, src, -1, temp.data(), size, 0, 0);
size = MultiByteToWideChar(932, 0, temp.data(), -1, 0, 0);
std::wstring dst(size, 0);
MultiByteToWideChar(932, 0, temp.c_str(), -1, dst.data(), size);
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"%s\n", dst.c_str());
//Try with different font
CONSOLE_FONT_INFOEX font = { sizeof(font) };
HANDLE hcout = GetStdHandle(STD_OUTPUT_HANDLE);
GetCurrentConsoleFontEx(hcout, FALSE, &font);
wcscpy_s(font.FaceName, L"MS Gothic");
SetCurrentConsoleFontEx(hcout, FALSE, &font);
std::wcout << dst << "\n";
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.