使用填充在控制台上显示格式化文本

时间:2015-11-18 08:38:43

标签: c# console-application padding

我打算以类似于以下内容的格式化方式编写控制台应用程序参数的说明:

The following options are possible:
    myOption:   Text do describe the option, but that should be splitted 
                to several lines if too big. Text should automatically 
                align by a fixed offset.

我已经有了一种方法将文本分割到正确的位置(假设我们不关心我们是否在任何单词的中间分开,只有当我们关心我们是否真的在字边界分裂时,我们才会复制事物)。但是我仍然坚持对齐选项说明。

这是到目前为止的代码:

public void DisplayHelpEx()
{
    var offset = this._options.Max(x => x.ParameterName.Length) + 6;
    Console.WriteLine("The following options are possible:");
    foreach (var option in this._corrections)
    {
        Console.Write((option.ParameterName + ": ").PadLeft(offset));
        WriteOffset(offset, option.Explanation);
    }
}

public void WriteOffset(int offset, string text)
{
    var numChars = TOTAL_NUMBER_CHARS_PER_LINE - offset;
    string line;

    while ((line = new String(text.Take(numChars).ToArray())).Any())
    {
        var s = line.PadLeft(numChars);
        Console.Write(s);
        Console.WriteLine();
        text= new String(text.Skip(numChars).ToArray());
    }
}

我尝试过很多.PadLeft.PadRight的组合,但无法让它发挥作用。

通过上述方法,我得到以下输出:

The following options are possible:
  myOption: Text do describe the option, but that should be splitted 
to several lines if too big. Text should automatically 
                        align by a fixed offset.

2 个答案:

答案 0 :(得分:1)

PadLeft获取文本并向左或向右添加一些空格,以便全文具有定义的宽度,请参阅jsfiddle

但是,在您的情况下,您不希望整个文本具有固定宽度(特别是如果您将来希望在字边界处很好地分割),而是在开头的偏移。那你为什么不在每一行的开头添加偏移空间呢?

private const string optionParameterName = "myOption";

private const string optionText =
  "Text do describe the option, but that should be splitted to several lines if too big.Text should automatically align by a fixed offset.";

private const int TOTAL_NUMBER_CHARS_PER_LINE = 60;

public void DisplayHelpEx()
{
  var offset = optionParameterName.Length + 6;
  Console.WriteLine("The following options are possible:");
  WriteOffset(offset, optionParameterName + ": ", optionText);
}

public void WriteOffset(int offset, string label, string text)
{
  var numChars = TOTAL_NUMBER_CHARS_PER_LINE - offset;
  string offsetString = new string(' ', offset);
  string line;

  bool firstLine = true;

  while ((line = new String(text.Take(numChars).ToArray())).Any())
  {
    if (firstLine)
    {
      Console.Write(label.PadRight(offset));
    }
    else
    {
      Console.Write(offsetString);
    }
    firstLine = false;

    Console.Write(line);
    Console.WriteLine();

    text = new String(text.Skip(numChars).ToArray());
  }
}

// output:
// The following options are possible:
// myOption:     Text do describe the option, but that should b
//               e splitted to several lines if too big.Text sh
//               ould automatically align by a fixed offset.

请注意,我在第一行使用了label.PadRight(offset)来确保带有标签的字符串被填充到正确的长度 - 这里填充是有用的,因为它允许我们使标签字符串完全准确宽度与其他偏移量相同。

答案 1 :(得分:1)

WriteOffset方法中,您使用text做了奇怪的事情并且很难跟进其修改

使用fiddle修改过的程序进行测试

public class Program
{
    static int TOTAL_NUMBER_CHARS_PER_LINE = 64;

    public static void Main()
    {       
        DisplayHelpEx();
    }

    // i only set test params here
    public static void DisplayHelpEx()
    {
        string ParameterName = "myOption";
        string Explanation = "Text do describe the option, but that should be splitted to several lines if too big. Text should automatically align by a fixed offset";
        int offset = ParameterName.Length + 6;

        Console.WriteLine("The following options are possible:");

        // print caption
        Console.Write((ParameterName + ": ").PadLeft(offset));
        // print help
        WriteOffset(offset, TOTAL_NUMBER_CHARS_PER_LINE - offset, Explanation); 
    }
    
    private static void WriteOffset(int offset, int width, string text)
    {         
        string pad = new String(' ', offset);   

        int i = 0;
        while (i < text.Length)
        { 
            // print text by 1 symbol 
            Console.Write(text[i]);
            i++;      
            if (i%width == 0)
            {
                // when line end reached, go to next
                Console.WriteLine();
                // make offset for new line
                Console.Write(pad);
            }  
        }
    }   
}