Console.WriteLine을 사용하여 열의 텍스트를 어떻게 정렬 할 수 있습니까?


78

일종의 열 표시가 있지만 끝 두 열이 올바르게 정렬되지 않은 것 같습니다. 이것은 내가 현재 가지고있는 코드입니다.

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

나는 신인 프로그래머라서 모든 조언을 이해하지 못할 수도 있지만 조언이 있다면 대단히 감사하겠습니다!


1
이 질문에 대한보다 일반적인 버전은 여기참조하십시오 . 거기에 대한 답변도 확인할 가치가 있습니다.
Adam Glauser 2014 년

답변:


13

임의의 공백 문자열이있는 열에 텍스트를 수동으로 정렬하는 대신 실제 탭 ( \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);
}

37
탭은 데이터 길이가 모두 비슷한 경우에만 잘 작동합니다. 길이가 다양한 데이터가있는 경우 형식 문자열과 함께 royas 응답을 사용해야합니다.
Tim

3
네, 훨씬 더 나은 대답입니다. 나는 그것을 보자 마자 찬성했지만 더 간단한 접근 방식이 더 효과적 일 경우를 대비하여 내 것을 떠났습니다. 내 것이 왜 받아 들여 졌는지 모르겠지만 ... :-)
Cody Gray

1
그리고 string.PadRight ()와 string.PadLeft ()에 대해 잊지 마세요
nhershy

가변 글꼴 너비로 텍스트를 정렬하려는 경우 royas 답변은 도움이되지 않습니다. 이 답변 과 같이 탭과 패딩 조합을 사용해야한다고 생각합니다 .

317

이 시도

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 를 참조 하십시오.


18
실제로 string.format 메서드를 전달할 필요가 없습니다. : 다른 말로하면 그것은 일을 같은 일이 될 것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);
토노 남

63

roya의 대답에 추가하십시오. 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 */);

5
msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspx 에는 "정렬"에 대한 설명서가 있습니다. 매우 유용합니다!
Frison Alexander

4
왼쪽 정렬하려면 다음과 같이 음수를 사용하십시오 $"{thirtyPercentValue,-10}"..
stomtech

7

나는 아주 오래된 스레드를 알고 있지만 제안 된 솔루션은 더 긴 문자열이있을 때 완전 자동이 아니 었습니다.

따라서 완전히 자동으로 수행되는 작은 도우미 메서드를 만들었습니다. 각 배열이 라인과 배열의 각 요소, 물론 라인의 요소를 나타내는 문자열 배열 목록을 전달하십시오.

이 방법은 다음과 같이 사용할 수 있습니다.

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


이것이 가장 정확한 답입니다. 그럼에도 불구하고 나는 항상 모든 라인이 선언하지 않는 것이 그 마지막 줄에 대한 방법을 개선 : pastebin.com/CVkavHgy
데이비드 에즈

Console.Write를 사용하여 "출력"을 인쇄하면 해당 isFirst부분을 제거 할 수 있습니다 . sb.AppendLine();foreach의 끝에서 수행하십시오 .
tomwaitforitmy

2

열 사이의 공백 대신 탭을 사용하거나 형식 문자열에서 열의 최대 크기를 설정할 수 있습니다.


2

서식 지정에 도움이되는 여러 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 을 사용하여 콘솔 서식을 지정할 수 있습니다 . † 예를 들어 string.Format다음을 사용하는 다른 답변에서와 같이 10의 고정 열 너비를 가진 그리드로 개체 목록의 서식을 지정합니다 .

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

pure보다 복잡해 보일 수 string.Format있지만 이제 사용자 정의 할 수 있습니다. 예를 들면 :

  • 당신은 내용에 따라 자동으로 크기 열에 원하는 경우, 교체 AddColumns(10, 10, 10, 10, 10)AddColumns(-1, -1, -1, -1, -1)( -1바로 가기입니다 GridLength.Auto, 당신이 더 많은 콘솔 창 너비의 비율을 포함, 옵션 크기 조정했다).

  • 숫자 열을 오른쪽으로 정렬 { Align = Right }하려면 셀의 이니셜 라이저에 추가하십시오 .

  • 열에 색상 { Color = Yellow }을 지정하려면 셀의 이니셜 라이저에 추가하십시오 .

  • 테두리 스타일 등을 변경할 수 있습니다.

† CsConsoleFormat은 제가 개발했습니다.


1

여기에 언급 된 라이브러리가 정말 마음에 들지만 패딩이나 수많은 문자열 조작을하는 것보다 더 간단 할 수있는 아이디어가있었습니다.

데이터의 최대 문자열 길이를 사용하여 커서를 수동으로 설정할 수 있습니다. 다음은 아이디어를 얻기위한 코드입니다 (테스트되지 않음).

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

행이 더 많으면 쉽게 외삽 할 수 있습니다.


0

약간의 패딩을 수행하십시오.

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

            }

이것은 적어도 나를 위해 잘 작동했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.