Printing fixed width strings that contain multi-byte characters
Asked Answered
L

1

7

I have some strings that are stored in multi-byte UTF8 format, and I'd like to print them to the console in a fixed-width space. I am doing this by:

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");

The filename variables are in ASCII format and work fine, but the titleUTF variables will print too short if they contain any multi-byte characters. I assume this is because the wprintf function includes each byte of the multi-byte characters when calculating the width. See below for output:

enter image description here

The "dash" character in the THPS2 title is actually a half-width Japanese character, this is what's breaking the wprintf function in this case.

I've tried using "%-32lS" but this prints garbage to the console, and I've tried lower case "s" but this also prints garbage. Any ideas how to get the fixed width print even with multi-byte characters?

EDIT:

Here is a screenshot showing the titleUDF variables in memory, along with the offending "THPS2" string bytes:

enter image description here

As you can see, the "dash" character is represented as 0xef 0xbd 0xb0

It's worth noting that I have to call:

SetConsoleCP(65001);
SetConsoleOutputCP(65001);

To get the multi-byte characters to show up properly. Also, I have to change the font in my console to one that has glyphs for these characters. I use NSimSun.

Latimer answered 17/2, 2020 at 8:39 Comment(2)
Could you give the code point of the problematic character or at least write it here so that we can to copy and paste it?Aerobic
@SergeBallesta See my editLatimer
T
0

I think, you will not be able to fix wprintf (or will write your full version of wprintf). So, there is simple/rough solution :( :

void PrintFilenameLine(const wchar_t* line1, const wchar_t* line2, const wchar_t* line3) {
  // Detect sizes of lines
  // Generate output string
}
Tjon answered 17/2, 2020 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.