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

Display formatted text on console using 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.

PadLeft 获取文本并向左或向右添加一些空格,以便全文具有定义的宽度,请参阅 https://msdn.microsoft.com/en-us/library/system.string.padleft(v=vs.110).aspx

但是,在您的情况下,您不希望 整个 文本具有固定宽度(尤其是如果您将来想在单词边界处很好地拆分),而是开头的 offset。那么为什么不直接在每一行的开头添加偏移空格,就像这样?

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) 以确保带有标签的字符串被填充到正确的长度——这里填充很有用,因为它允许我们制作标签字符串的宽度与其他偏移量完全相同。

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