Печать строк фиксированной ширины, содержащих многобайтовые символы - PullRequest
7 голосов
/ 17 февраля 2020

У меня есть несколько строк, которые хранятся в многобайтовом формате 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");

Переменные имени файла имеют формат ASCII и работают нормально, но переменные titleUTF будут печататься слишком короткими, если они содержат какие-либо многобайтовые символы. Я предполагаю, что это потому, что функция wprintf включает каждый байт многобайтовых символов при расчете ширины. См. Ниже вывод:

enter image description here

Символ "da sh" в названии THPS2 на самом деле является японским символом половинной ширины, вот что в этом случае нарушается функция wprintf.

Я пытался использовать "% -32lS", но это выводит на консоль мусор, и я пробовал строчные буквы "s", но это также выводит мусор. Любые идеи, как получить печать фиксированной ширины даже с многобайтовыми символами?

РЕДАКТИРОВАТЬ:

Вот скриншот, показывающий переменные titleUDF в памяти, наряду с ошибочными строковыми байтами "THPS2" :

enter image description here

Как видите, символ "da sh" представлен в виде 0xef 0xbd 0xb0

Стоит отметить что мне нужно позвонить:

SetConsoleCP(65001);
SetConsoleOutputCP(65001);

, чтобы заставить многобайтовые символы правильно отображаться. Кроме того, я должен изменить шрифт в моей консоли на шрифт с этими символами. Я использую NSimSun.

1 Ответ

0 голосов
/ 17 февраля 2020

Я думаю, вы не сможете исправить wprintf (или напишете свою полную версию wprintf). Итак, есть простое / грубое решение :(:

void PrintFilenameLine(const wchar_t* line1, const wchar_t* line2, const wchar_t* line3) {
  // Detect sizes of lines
  // Generate output string
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...