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

发布于 2024-10-07 21:10:06 字数 677 浏览 5 评论 0原文

我有一种列显示,但最后两列似乎没有正确对齐。这是我现在的代码:

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

I have a sort of column display, but the end two column's seem to not be aligning correctly. This is the code I have at the moment:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

记忆里有你的影子 2024-10-14 21:10:06

尝试一下

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

,其中大括号内的第一个数字是索引,第二个数字是对齐方式。第二个数字的符号指示字符串应该左对齐还是右对齐。使用负数进行左对齐。

或者看看
http://msdn.microsoft.com/en-我们/library/aa331875(v=vs.71).aspx

Try this

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

where the first number inside the curly brackets is the index and the second is the alignment. The sign of the second number indicates if the string should be left or right aligned. Use negative numbers for left alignment.

Or look at
http://msdn.microsoft.com/en-us/library/aa331875(v=vs.71).aspx

黑凤梨 2024-10-14 21:10:06

只是为了补充罗亚的答案。在 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 */);

Just to add to roya's answer. In c# 6.0 you can now use string interpolation:

Console.WriteLine($"{customer[DisplayPos],10}" +
                  $"{salesFigures[DisplayPos],10}" +
                  $"{feePayable[DisplayPos],10}" +
                  $"{seventyPercentValue,10}" +
                  $"{thirtyPercentValue,10}");

This can actually be one line without all the extra dollars, I just think it makes it a bit easier to read like this.

And you could also use a static import on System.Console, allowing you to do this:

using static System.Console;

WriteLine(/* write stuff */);
颜漓半夏 2024-10-14 21:10:06

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

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

Instead of trying to manually align the text into columns with arbitrary strings of spaces, you should embed actual tabs (the \t escape sequence) into each output string:

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);
}
﹏半生如梦愿梦如真 2024-10-14 21:10:06

我知道,非常旧的线程,但当周围有较长的字符串时,建议的解决方案并不是全自动的。

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

该方法可以这样使用:

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

辅助方法如下:

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

希望这对某人有帮助。来源来自我博客中的一篇文章: http://dev.flauschig.ch/wordpress /?p=387

I know, very old thread but the proposed solution was not fully automatic when there are longer strings around.

I therefore created a small helper method which does it fully automatic. Just pass in a list of string array where each array represents a line and each element in the array, well an element of the line.

The method can be used like this:

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

The helper method is as follows:

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

Hope this helps someone. The source is from a post in my blog here: http://dev.flauschig.ch/wordpress/?p=387

当爱已成负担 2024-10-14 21:10:06

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

ConsoleTableExt

ConsoleTableExt 是一个简单的库,它允许格式化表格,包括没有网格线的表格。 (更流行的软件包 ConsoleTables 似乎不支持无边框表格。)以下是格式化对象列表,其中列的大小根据其内容:

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

如果您需要更多功能,可以使用 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) 替换为 AddColumns(-1, -1, -1, -1, -1)-1GridLength.Auto 的快捷方式,您有更多的大小选项,包括控制台窗口宽度的百分比)。

  • 如果要将数字列向右对齐,请将 { Align = Right } 添加到单元格的初始值设定项。

  • 如果要为列着色,请将 { Color = Yellow } 添加到单元格的初始值设定项。

  • 您可以更改边框样式等。

†​​ CsConsoleFormat 是我开发的。

There're several NuGet packages which can help with formatting. In some cases the capabilities of string.Format are enough, but you may want to auto-size columns based on content, at least.

ConsoleTableExt

ConsoleTableExt is a simple library which allows formatting tables, including tables without grid lines. (A more popular package ConsoleTables doesn't seem to support borderless tables.) Here's an example of formatting a list of objects with columns sized based on their content:

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

If you need more features than that, any console formatting can be achieved with CsConsoleFormat.† For example, here's formatting of a list of objects as a grid with fixed column width of 10, like in the other answers using 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)
                    })
                )
        ));

It may look more complicated than pure string.Format, but now it can be customized. For example:

  • If you want to auto-size columns based on content, replace AddColumns(10, 10, 10, 10, 10) with AddColumns(-1, -1, -1, -1, -1) (-1 is a shortcut to GridLength.Auto, you have more sizing options, including percentage of console window's width).

  • If you want to align number columns to the right, add { Align = Right } to a cell's initializer.

  • If you want to color a column, add { Color = Yellow } to a cell's initializer.

  • You can change border styles and more.

† CsConsoleFormat was developed by me.

云醉月微眠 2024-10-14 21:10:06

您可以使用制表符代替列之间的空格,和/或在格式字符串中设置列的最大大小...

You could use tabs instead of spaces between columns, and/or set maximum size for a column in format strings ...

冷了相思 2024-10-14 21:10:06

做一些填充,即

          public static void prn(string fname, string fvalue)
            {
                string outstring = fname.PadRight(20)  +"\t\t  " + fvalue;
                Console.WriteLine(outstring);

            }

这效果很好,至少对我来说。

Do some padding, i.e.

          public static void prn(string fname, string fvalue)
            {
                string outstring = fname.PadRight(20)  +"\t\t  " + fvalue;
                Console.WriteLine(outstring);

            }

This worked well, at least for me.

幻梦 2024-10-14 21:10:06

通过将对齐方式放在“:”格式字符前面,可以将对齐方式与字符串插值结合起来。

Console.WriteLine($"{name,40} {MaterialArea,10:N2}m² {MaterialWeightInLbs,10:N0}lbs {Cost,10:C2}");

The alignment can be combined with string interpolation by putting it in front of the ':' format character.

Console.WriteLine(
quot;{name,40} {MaterialArea,10:N2}m² {MaterialWeightInLbs,10:N0}lbs {Cost,10:C2}");
长安忆 2024-10-14 21:10:06

我真的很喜欢这里提到的那些库,但我有一个想法,这可能比仅仅填充或进行大量字符串操作更简单,

您可以使用数据的最大字符串长度手动设置光标。下面是一些代码来了解这个想法(未测试):

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

如果您有更多行,您可以轻松推断。

I really like those libraries mentioned here but I had an idea that could be simpler than just padding or doing tons of string manipulations,

You could just manually set your cursor using the maximum string length of your data. Here's some code to get the idea (not tested):

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

you could easily extrapolate if you have more rows.

伏妖词 2024-10-14 21:10:06
    public static void PrintAttempts(List<Attempt> attemptList)
    {
        //Format for columns in Console.Write
        Console.WriteLine("{0,-4} {1,-24} {2,-50} {3,-60} {4,-70} {5,-80}", "Id", "Error", "Response", "Attempt No.", "User Name", "Date-Time");
        foreach (var attempt in attemptList)
        {
            Console.WriteLine($"{attempt.Id,-4} {attempt.ErrorType,-24} {attempt.Response,-50} {attempt.CurrentAttempt,-60} {attempt.UserName,-70} {attempt.DateTimeAttempted,-80}");
        }

    }

这是一个带有列表对象的相当简单的示例。我正在输入标题和数据并使用字符串插值。对于标题,第一个数字是从 0 开始的列索引。第二个数字可以是负数(左对齐)或正数(右对齐)。然后在循环中,我放置 $"{object.field, -4}"

表示我希望该字段从第四个位置开始左对齐。

    public static void PrintAttempts(List<Attempt> attemptList)
    {
        //Format for columns in Console.Write
        Console.WriteLine("{0,-4} {1,-24} {2,-50} {3,-60} {4,-70} {5,-80}", "Id", "Error", "Response", "Attempt No.", "User Name", "Date-Time");
        foreach (var attempt in attemptList)
        {
            Console.WriteLine(
quot;{attempt.Id,-4} {attempt.ErrorType,-24} {attempt.Response,-50} {attempt.CurrentAttempt,-60} {attempt.UserName,-70} {attempt.DateTimeAttempted,-80}");
        }

    }

Here is a fairly simple example with a list object. I am putting in the headings and data and using string interpolation. For the headings, the first number is the column index starting at a 0 based count. The second number is either negative (left align) or positive (right align). Then within the loop, I place the $"{object.field, -4}"

Indicating I want that field left aligned starting at the 4th position.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文