Как отформатировать китайские иероглифы так, чтобы они помещались в столбцы?

Я пытаюсь напечатать некоторую информацию по столбцам. Все работает с латинскими символами, но когда печатаются китайские символы, столбцы перестают выравниваться. Рассмотрим пример:

var latinPresentation1 = "some text".PadRight(30) + "| " + 23;
var latinPresentation2 = "some longer text".PadRight(30) + "| " + 23;

Console.WriteLine(latinPresentation1);
Console.WriteLine(latinPresentation2);

Console.WriteLine("..............................................");

var chinesePresentation1 = "一些文字".PadRight(30) + " | " + 23;
var chinesePresentation2 = "一些較長的文字".PadRight(30) + "| " + 23;

Console.WriteLine(chinesePresentation1);
Console.WriteLine(chinesePresentation2);

Вывод:

some text                     | 23
some longer text              | 23
.................................................
一些文字                           | 23
一些較長的文字                       | 23

Как видно, китайский не выровнен по столбцам. Важное примечание: это просто представление проблемы; он не будет использоваться в консольном приложении. Кто-нибудь может мне с этим помочь?

Эти китайские символы имеют ширину 2. Если бы можно было выяснить, для каких именно символов это верно, вы могли бы написать собственный PadRight-Method, который учитывает это, если не будет лучшего решения.

CSharpie 16.01.2019 12:55

@CSharpie - Я проверил это, и похоже, что китайские иероглифы не нормализованы. Нельзя предположить, что 1 китайский символ = 2 латинских символа.

artsch 16.01.2019 13:54

вот почему я сказал, что вам нужно выяснить, для каких символов это правда

CSharpie 16.01.2019 14:04

@artsch как будет использоваться текст? Консольная поддержка в Windows была очень плохой до релизов последний для инсайдеров Windows 10. До недавнего времени вам приходилось явно настраивать окно консоли для отображения Unicode. Протестируйте свой код в стеке презентаций, который вы собираетесь использовать (ASP.NET, WPF, Winforms), и используйте функции их для выравнивания текста. Скорее всего, у вас не возникнет проблем

Panagiotis Kanavos 16.01.2019 14:17

@artsch Проверьте Командная строка Windows: текстовый буфер вывода Unicode и UTF-8, чтобы узнать, почему в консоли такой беспорядок, и что делается, чтобы это исправить. Статья опубликована в ноябре 2018 г.

Panagiotis Kanavos 16.01.2019 14:20

@PanagiotisKanavos - он будет отправлен на принтер в виде обычного текста. Но не стандартный, это будет принтер чеков.

artsch 16.01.2019 14:32

@artsch это плохо. В этом случае вы делать должны иметь дело с ограничениями - другого уровня представления нет. Размер каждого глифа зависит от используемого шрифта. PadRight ничего не знает о шрифтах, только о символах. Размер каждого глифа будет зависеть от шрифтов принтер. MeasureText может помочь, если вы найдете такой же или эквивалентный шрифт в Windows.

Panagiotis Kanavos 16.01.2019 14:38

@artsch, с другой стороны, в консоли Windows отсутствуют управляющие команды, используемые для разметки текста. POS-принтеры обычно поддерживают команды ESC / POS, и одна из них используется установить горизонтальные позиции табуляции, как и Word. Вместо заполнения вы можете установить позиции табуляции один раз, а затем использовать табуляции в каждой текстовой строке, чтобы текст отображался там, где вы хотите.

Panagiotis Kanavos 16.01.2019 14:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
8
712
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я попробовал приведенный ниже код, так как у меня нет поддержки китайского языка, я не могу его протестировать.

var latinPresentation1 = "some text" ;
var latinPresentation2 = "some longer text";

Console.WriteLine(String.Format("{0,-30} {1,-10} ", latinPresentation1, "| " + 23));
Console.WriteLine(String.Format("{0,-30} {1,-10} ", latinPresentation2, "| " + 23));

Console.WriteLine("..............................................");

var chinesePresentation1 = "一些文字";
var chinesePresentation2 = "一些較長的文字";

Console.WriteLine(String.Format("{0,-30} {1,-10} ", chinesePresentation1, "| " + 23));
Console.WriteLine(String.Format("{0,-30} {1,-10} ", chinesePresentation2, "| " + 23));

Это не работает -> Это в основном тот же код. Все, что вы сделали, это вместо этого использовали string.Format, которая делает то же самое внутри.

CSharpie 16.01.2019 12:54
Ответ принят как подходящий

Вы можете использовать метод TextRenderer.MeasureText из сборки System.Windows.Forms для построения выходного текста на основе ширины строки, а не количества символов.

Вот метод утилиты:

public static string FillWithSpaces(this string text, int width, Font font)
{
    while (TextRenderer.MeasureText(text, font).Width < width)
    {
        text += ' ';
    }
    return text;
}

И использование:

var font = new Font("Courier New", 10.0F);
var padding = 340;

var latinPresentation1 = "some text ".FillWithSpaces(padding, font) + "| 23";
var latinPresentation2 = "some longer text".FillWithSpaces(padding, font) + "| 23";

var chinesePresentation1 = "一些文字".FillWithSpaces(padding, font) + "| 23";
var chinesePresentation2 = "一些較長的文字".FillWithSpaces(padding, font) + "| 23";

var result = latinPresentation1 + Environment.NewLine +
             latinPresentation2 + Environment.NewLine +
             ".............................................." + Environment.NewLine +
             chinesePresentation1 + Environment.NewLine +
             chinesePresentation2; 

Решение требует использования параметра заполнения (в пикселях) и шрифта.

Это не идеально, но похоже, что идеального решения для этого случая не существует. Подойдет, спасибо.

artsch 16.01.2019 15:26

Я могу представить только одно общее решение с заполнением. Вы должны использовать моноширинный шрифт, и все символы обоих алфавитов должны быть одного размера. Фактически функция PaddingRight просто добавляет заданное количество символов в строку. Но отображаемый размер строки также зависит от шрифта. Если вы используете моноширинный шрифт, он будет работать, в других случаях даже для латинских символов - нет. На мой взгляд, лучше решать проблему для каждого конкретного вывода, который вы собираетесь использовать, потому что строка itsefl ничего не знает о том, как она будет отображаться, и более того, она не должна знать об этом.

Другие вопросы по теме