How do I format Chinese characters so they fit the columns?

Viewed 879

I am trying to print some information in a column-oriented way. Everything works well for Latin characters, but when Chinese characters are printed, the columns stop being aligned. Let's consider an example:

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

Output:

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

As one can see, the Chinese is not aligned to columns. Important note: this is just a presentation of the problem; it won't be used in a console app. Can anyone help me with this?

3 Answers

You can use the TextRenderer.MeasureText method from System.Windows.Forms assembly to build the output text basing on string width, instead of characters count.

Here's the util method:

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

And the usage:

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; 

The solution requires padding parameter (in px) and font used.

I can imagine only one generic solution with padding. You have to use monospace font and all symbols of both alphabets must be the same size. Actually PaddingRight function just adds provided amount of symbols to the string. But displayed size of string also depends on font. In case you use monospace font it will work, in other cases, even for latin symbols it will not. In my opinion, it's better to solve the problem for each particular output which you are going to use, because string itsefl knows nothing about how it will be rendered and more than that it should not aware about it.

I tried the below code, as I don't have Chinese support I cannot able to test it.

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