打印包含多字节字符的固定宽度字符串

Jas*_*ska 7 c++ printf fixed-width multibyte-characters

我有一些以多字节 UTF8 格式存储的字符串,我想将它们以固定宽度的空间打印到控制台。我这样做:

wprintf(L"////////////// BLOCK 1 ///////////////   ////////////// BLOCK 2 ///////////////   ////////////// BLOCK 3 ///////////////\n");
wprintf(L"// %-32S //   // %-32S //   // %-32S //\n", mymemcard[0].filename, mymemcard[1].filename, mymemcard[2].filename);
wprintf(L"// %-32S //   // %-32S //   // %-32S //\n", mymemcard[0].titleUTF, mymemcard[1].titleUTF, mymemcard[2].titleUTF);
wprintf(L"//////////////////////////////////////   //////////////////////////////////////   //////////////////////////////////////\n\n");
Run Code Online (Sandbox Code Playgroud)

文件名变量采用 ASCII 格式并且工作正常,但如果 titleUTF 变量包含任何多字节字符,它们将打印得太短。我认为这是因为 wprintf 函数在计算宽度时包括多字节字符的每个字节。请参阅下面的输出:

在此处输入图片说明

THPS2 标题中的“破折号”字符实际上是一个半角日文字符,这就是在这种情况下破坏 wprintf 功能的原因。

我试过使用 "%-32lS" 但这会向控制台打印垃圾,我试过小写的 "s" 但这也会打印垃圾。即使使用多字节字符,如何获得固定宽度打印的任何想法?

编辑:

这是一个屏幕截图,显示了内存中的 titleUDF 变量,以及有问题的“THPS2”字符串字节:

在此处输入图片说明

如您所见,“破折号”字符表示为 0xef 0xbd 0xb0

值得注意的是,我必须调用:

SetConsoleCP(65001);
SetConsoleOutputCP(65001);
Run Code Online (Sandbox Code Playgroud)

使多字节字符正确显示。此外,我必须将控制台中的字体更改为具有这些字符的字形的字体。我使用 NSimSun。

小智 0

我认为,您将无法修复 wprintf (或者将编写完整版本的 wprintf)。所以,有一个简单/粗略的解决方案:(:

void PrintFilenameLine(const wchar_t* line1, const wchar_t* line2, const wchar_t* line3) {
  // Detect sizes of lines
  // Generate output string
}
Run Code Online (Sandbox Code Playgroud)