C# 如何使用Console.WriteLine对齐列中的文本?

C# 如何使用Console.WriteLine对齐列中的文本?,c#,console,tabs,alignment,vertical-alignment,C#,Console,Tabs,Alignment,Vertical Alignment,我有一种列显示,但两列的末端似乎没有正确对齐。这是我目前掌握的代码: Console.WriteLine("Customer name " + "sales " + "fee to be paid " + "70% value " + "30% value"); for (int DisplayPos = 0; DisplayPos < LineNum; DisplayPos = DisplayPos + 1

我有一种列显示,但两列的末端似乎没有正确对齐。这是我目前掌握的代码:

Console.WriteLine("Customer name    " 
    + "sales          " 
    + "fee to be paid    " 
    + "70% value       " 
    + "30% value");
for (int DisplayPos = 0; DisplayPos < LineNum; DisplayPos = DisplayPos + 1)
{
    seventy_percent_value = ((fee_payable[DisplayPos] / 10.0) * 7);
    thirty_percent_value = ((fee_payable[DisplayPos] / 10.0) * 3);          
    Console.WriteLine(customer[DisplayPos] + "         " 
        + sales_figures[DisplayPos] + "               " 
        + fee_payable[DisplayPos] + "           " 
        + seventy_percent_value + "           " 
        + thirty_percent_value);
}
Console.WriteLine(“客户名称”
+“销售”
+“需支付的费用”
+“70%价值”
+“30%的价值”);
用于(int DisplayPos=0;DisplayPos
我是一个新手程序员,所以我可能不理解所有的建议,但如果你有任何建议,将不胜感激

试试这个

Console.WriteLine("{0,10}{1,10}{2,10}{3,10}{4,10}",
  customer[DisplayPos],
  sales_figures[DisplayPos],
  fee_payable[DisplayPos], 
  seventy_percent_value,
  thirty_percent_value);
其中,花括号内的第一个数字是索引,第二个是对齐。第二个数字的符号表示字符串应该左对齐还是右对齐。左对齐使用负数

或者看看

您可以使用制表符而不是列之间的空格,和/或为格式字符串中的列设置最大大小…

您应该将实际制表符(转义序列)嵌入到每个输出字符串中,而不是尝试手动将文本对齐到带有任意空格字符串的列中:

Console.WriteLine("Customer name" + "\t"
    + "sales" + "\t" 
    + "fee to be paid" + "\t" 
    + "70% value" + "\t" 
    + "30% value");
for (int DisplayPos = 0; DisplayPos < LineNum; DisplayPos++)
{
    seventy_percent_value = ((fee_payable[DisplayPos] / 10.0) * 7);
    thirty_percent_value = ((fee_payable[DisplayPos] / 10.0) * 3);          
    Console.WriteLine(customer[DisplayPos] + "\t" 
        + sales_figures[DisplayPos] + "\t" 
        + fee_payable + "\t\t"
        + seventy_percent_value + "\t\t" 
        + thirty_percent_value);
}
Console.WriteLine(“客户名称”+“\t”
+“销售”+“\t”
+“需要支付的费用”+“\t”
+“70%值”+“\t”
+“30%的价值”);
对于(int DisplayPos=0;DisplayPos
我知道,这是一个非常古老的线程,但当周围有较长的字符串时,建议的解决方案不是完全自动的

因此,我创建了一个小助手方法,它可以完全自动完成。只需传入一个字符串数组列表,其中每个数组表示一行和数组中的每个元素,以及该行的一个元素

该方法可以如下使用:

var lines = new List<string[]>();
lines.Add(new[] { "What", "Before", "After"});
lines.Add(new[] { "Name:", name1, name2});
lines.Add(new[] { "City:", city1, city2});
lines.Add(new[] { "Zip:", zip1, zip2});
lines.Add(new[] { "Street:", street1, street2});
var output = ConsoleUtility.PadElementsInLines(lines, 3);
var行=新列表();
添加(新的[]{“What”,“Before”,“After”});
添加(新[]{“Name:”,name1,name2});
添加(新[]{“城市:”,城市1,城市2});
添加(新的[]{“Zip:,zip1,zip2});
添加(新[]{“街道:”,街道1,街道2});
var输出=可操控性。PadElementsInLines(第3行);
助手方法如下所示:

public static class ConsoleUtility
{
    /// <summary>
    /// Converts a List of string arrays to a string where each element in each line is correctly padded.
    /// Make sure that each array contains the same amount of elements!
    /// - Example without:
    /// Title Name Street
    /// Mr. Roman Sesamstreet
    /// Mrs. Claudia Abbey Road
    /// - Example with:
    /// Title   Name      Street
    /// Mr.     Roman     Sesamstreet
    /// Mrs.    Claudia   Abbey Road
    /// <param name="lines">List lines, where each line is an array of elements for that line.</param>
    /// <param name="padding">Additional padding between each element (default = 1)</param>
    /// </summary>
    public static string PadElementsInLines(List<string[]> lines, int padding = 1)
    {
        // Calculate maximum numbers for each element accross all lines
        var numElements = lines[0].Length;
        var maxValues = new int[numElements];
        for (int i = 0; i < numElements; i++)
        {
            maxValues[i] = lines.Max(x => x[i].Length) + padding;
        }
        var sb = new StringBuilder();
        // Build the output
        bool isFirst = true;
        foreach (var line in lines)
        {
            if (!isFirst)
            {
                sb.AppendLine();
            }
            isFirst = false;
            for (int i = 0; i < line.Length; i++)
            {
                var value = line[i];
                // Append the value with padding of the maximum length of any value for this element
                sb.Append(value.PadRight(maxValues[i]));
            }
        }
        return sb.ToString();
    }
}
公共静态类控制台
{
/// 
///将字符串数组列表转换为字符串,其中每行中的每个元素都正确填充。
///确保每个数组包含相同数量的元素!
///-例如,没有:
///名称街
///Roman Sesamstreet先生
///克劳迪娅·阿比夫人路
///-例如:
///名称街
///Roman Sesamstreet先生
///克劳迪娅·阿比夫人路
///列出行,其中每行都是该行的元素数组。
///每个元素之间的附加填充(默认值=1)
/// 
公共静态字符串PadElementsInLines(列表行,int padding=1)
{
//计算所有行中每个元素的最大数量
var numElements=行[0]。长度;
var maxValues=新整数[numElements];
对于(int i=0;ix[i].长度)+填充;
}
var sb=新的StringBuilder();
//构建输出
bool isFirst=true;
foreach(行中的var行)
{
如果(!isFirst)
{
(某人);
}
isFirst=false;
for(int i=0;i

希望这对别人有帮助。来源于我博客中的一篇帖子:

只是为了补充罗亚的答案。在c#6.0中,现在可以使用字符串插值:

Console.WriteLine($"{customer[DisplayPos],10}" +
                  $"{salesFigures[DisplayPos],10}" +
                  $"{feePayable[DisplayPos],10}" +
                  $"{seventyPercentValue,10}" +
                  $"{thirtyPercentValue,10}");
这实际上可以是一行,没有额外的钱,我只是觉得这样读起来更容易一些

您还可以在System.Console上使用静态导入,允许您执行以下操作:

using static System.Console;

WriteLine(/* write stuff */);

有几个NuGet包可以帮助格式化。在某些情况下,
string.Format
的功能已经足够了,但至少您可能希望根据内容自动调整列的大小

控制台文本 是一个简单的库,它允许格式化表格,包括没有网格线的表格。(一个更流行的软件包似乎不支持无边界表。)下面是一个格式化对象列表的示例,其中列的大小取决于它们的内容:

ConsoleTableBuilder
    .From(orders
        .Select(o => new object[] {
            o.CustomerName,
            o.Sales,
            o.Fee,
            o.Value70,
            o.Value30
        })
        .ToList())
    .WithColumn(
        "Customer",
        "Sales",
        "Fee",
        "70% value",
        "30% value")
    .WithFormat(ConsoleTableBuilderFormat.Minimal)
    .WithOptions(new ConsoleTableBuilderOption { DividerString = "" })
    .ExportAndWriteLine();
CsConsoleFormat 如果您需要更多的功能,任何控制台格式都可以通过。†例如,以下是将对象列表格式化为固定列宽为10的网格,就像使用
string.Format的其他答案一样:

ConsoleRenderer.RenderDocument(
    new Document { Color = ConsoleColor.Gray }
        .AddChildren(
            new Grid { Stroke = LineThickness.None }
                .AddColumns(10, 10, 10, 10, 10)
                .AddChildren(
                    new Div("Customer"),
                    new Div("Sales"),
                    new Div("Fee"),
                    new Div("70% value"),
                    new Div("30% value"),
                    orders.Select(o => new object[] {
                        new Div().AddChildren(o.CustomerName),
                        new Div().AddChildren(o.Sales),
                        new Div().AddChildren(o.Fee),
                        new Div().AddChildren(o.Value70),
                        new Div().AddChildren(o.Value30)
                    })
                )
        ));
它看起来可能比纯的
string.Format
更复杂,但现在它可以自定义。例如:

  • 如果要根据内容自动调整列的大小,请将
    AddColumns(10,10,10,10,10,10)
    替换为
    AddColumns(-1,-1,-1,-1)
    -1
    GridLength.auto的快捷方式,您有更多的大小选择,包括控制台窗口宽度的百分比)

  • 如果要对齐数字列
    var column1[] = {"test", "longer test", "etc"}
    var column2[] = {"data", "more data", "etc"}
    var offset = strings.OrderByDescending(s => s.Length).First().Length;
    for (var i = 0; i < column.Length; i++) {
        Console.Write(column[i]);
        Console.CursorLeft = offset + 1;
        Console.WriteLine(column2[i]);
    }
    
              public static void prn(string fname, string fvalue)
                {
                    string outstring = fname.PadRight(20)  +"\t\t  " + fvalue;
                    Console.WriteLine(outstring);
    
                }