Как выровнять текст в столбцах, используя Console.WriteLine? - PullRequest
74 голосов
/ 15 декабря 2010

У меня есть своего рода отображение столбцов, но последние два столбца, кажется, не выравниваются правильно. Вот код, который у меня есть на данный момент:

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

Я начинающий программист, поэтому я могу не понимать всех данных советов, но если у вас есть какие-либо советы, это будет с благодарностью!

Ответы [ 7 ]

280 голосов
/ 15 декабря 2010

Попробуйте это

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-us/library/aa331875(v=vs.71).aspx

43 голосов
/ 07 декабря 2015

Просто чтобы добавить ответ Роя.В 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 */);
12 голосов
/ 15 декабря 2010

Вместо того, чтобы пытаться вручную выровнять текст в столбцы с произвольными строками пробелов, вы должны вставлять фактические вкладки (escape-последовательность \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);
}
6 голосов
/ 10 декабря 2014

Я знаю, очень старая тема, но предлагаемое решение не было полностью автоматическим, когда вокруг более длинные строки.

Поэтому я создал небольшой вспомогательный метод, который делает его полностью автоматическим. Просто передайте список строкового массива, где каждый массив представляет собой строку, а каждый элемент массива - элемент строки.

Метод можно использовать так:

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

2 голосов
/ 01 марта 2018

Существует несколько пакетов 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) (-1 - это ярлык для GridLength.Auto, у вас есть большепараметры размера, включая процент ширины окна консоли).

  • Если вы хотите выровнять числовые столбцы вправо, добавьте { Align = Right } к инициализатору ячейки.

  • Если вы хотите покрасить столбец, добавьте { Color = Yellow } к инициализатору ячейки.

  • Вы можете изменить стили границ и многое другое.

† CsConsoleFormat был разработан мной.

2 голосов
/ 15 декабря 2010

Вы можете использовать вкладки вместо пробелов между столбцами и / или установить максимальный размер столбца в строках формата ...

1 голос
/ 09 июня 2018

Мне действительно нравятся упомянутые здесь библиотеки, но у меня была идея, которая может быть проще, чем просто заполнение или выполнение множества манипуляций со строками,

Вы можете просто установить курсор вручную, используя максимальную длину строки ваших данных. Вот некоторый код, чтобы получить идею (не проверено):

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

Вы можете легко экстраполировать, если у вас есть больше строк.

...