[英]Printing wchar_t to console in C++
I have made a simple program that will read in a PS1 Memory Card binary file and display it's contents in the console using C++ in Visual Studio.我制作了一个简单的程序,它将读取 PS1 存储卡二进制文件,并在 Visual Studio 中使用 C++ 在控制台中显示其内容。 The game titles are encoded in the memory in Shift-JIS format, so I used the MultiByteToWideChar function to convert them:游戏标题在内存中以 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);
My problem is now that I can't get the lTitleL variable to print to the console.我现在的问题是我无法将 lTitleL 变量打印到控制台。 I've tried cout, wcout, printf, wprintf, I can't get them to work!我试过 cout、wcout、printf、wprintf,我无法让它们工作! I know that the lTitleL variable proiperly holds the title since I can see it in the debugger.我知道 lTitleL 变量正确地保存了标题,因为我可以在调试器中看到它。 When I call any of the print functions I've tried, simply nothing gets printed.当我调用我尝试过的任何打印函数时,根本没有打印任何内容。 ANy help would be appreciated!任何帮助,将不胜感激! Thanks.谢谢。
BIG EDIT:大编辑:
OK, so here's where I am with this:好的,这就是我的情况:
// 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;
///////////////////////////////////
To help visualise the output of this, here's a screenshot of the console using the NSimSun font:为了帮助可视化输出,以下是使用 NSimSun 字体的控制台屏幕截图:
And here with Consolas font:在这里使用 Consolas 字体:
Now for my question: I don't particularly like the NSimSun font, are there any others out there that look more like the Consolas font that do contain all the glyphs for the full/half width Japanese characters?现在我的问题是:我不是特别喜欢 NSimSun 字体,是否还有其他字体看起来更像 Consolas 字体,它们确实包含全/半宽日语字符的所有字形? If so, how can I package them into my Console app so that it's portable?如果是这样,我如何将它们打包到我的控制台应用程序中以使其可移植?
Thanks!谢谢!
Windows has limited support for printing Unicode on console. Windows 对在控制台上打印 Unicode 的支持有限。 Test your conversion by using MessageBoxW(0, lTitleL, 0, 0)
which is guaranteed to succeed, as long as the conversion was okay.使用MessageBoxW(0, lTitleL, 0, 0)
测试您的转换,只要转换正常,就可以保证成功。
To print to console window, you have to call _setmode(_fileno(stdout), _O_U16TEXT);
要打印到控制台窗口,您必须调用_setmode(_fileno(stdout), _O_U16TEXT);
in order to print characters out of ASCII range.为了打印超出 ASCII 范围的字符。
Stick with std::wcout
or wprintf(L"%s", str)
坚持使用std::wcout
或wprintf(L"%s", str)
There is an additional problem if the console does not support the right font.如果控制台不支持正确的字体,还有一个问题。 You have to try different fonts.你必须尝试不同的字体。 See example below.请参阅下面的示例。 Also consider using std::wstring
which has automatic cleanup.还可以考虑使用具有自动清理功能的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.