我制作了一个简单的程序,它将读取 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;
///////////////////////////////////
- MultiByteToWideChar 将 Shift-JIS 输入字符串转换为宽字符。
- 将其打印到控制台以进行调试。
- 现在的问题是 PS1 存储卡以全角形式存储所有字符,因此我使用 LCMapStringEX 将它们转换为半角以获得更好的输出。
- 将其打印到控制台以进行调试。
- 如果我很乐意使用 WriteConsoleW,这就足够了,但如果不是,那么一个问题是某些标点符号编码奇怪,并且使用 std::wcout 或 wprintf() 不能很好地打印。例如,连字符存储为 U+FF70 - “Halfwidth Katakana-Hiragana Prolonged Sound Mark”(转换为半角后),无论使用哪种字体,它们都只会显示为问号(但是,它们确实可以正确打印使用 WriteConsoleW)。
- 因此,我现在可以使用 WideCharToMultiByte,使用 UTF-8 代码页来获取一个使用 std::wcout 或 wprintf() 很好地打印到控制台的字符串版本。但是,我必须同时调用 SetConsoleCP(65001) 和 SetConsoleOutputCP(65001) 才能正确打印,否则多字节字符(如我提到的 U+FF70)会逐字节打印。
- 最后,要显示任何不寻常的字符,我需要选择一种可以显示它们的字体。我发现在我的控制台中可以使用默认字体的唯一字体是 NSimSun 和 SimSun-ExtB,其他字体似乎都不包含日文字符(至少对于 U+FF70 字符)。
为了帮助可视化它的输出,这里是使用 NSimSun 字体的控制台截图:
在这里使用 Consolas 字体:
现在我的问题是:我不是特别喜欢 NSimSun 字体,是否还有其他看起来更像 Consolas 字体的字体,包含全角/半角日文字符的所有字形?如果是这样,我如何将它们打包到我的控制台应用程序中以便它是可移植的?
谢谢!