¿Cómo puedo alinear texto en columnas usando Console.WriteLine?

Tengo una especie de visualización de columna, pero las dos últimas columnas parecen no alinearse correctamente. Este es el código que tengo en este momento:

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

Soy un progtwigdor novato, por lo que es posible que no entienda todos los consejos dados, pero si tiene algún consejo, lo agradecería mucho.

En lugar de tratar de alinear manualmente el texto en columnas con cadenas de espacios arbitrarias, debe incrustar las tabs reales (la secuencia \t escape) en cada cadena de salida:

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

Prueba esto

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

donde el primer número dentro de los corchetes es el índice y el segundo es la alineación. El signo del segundo número indica si la cadena debe estar alineada a la izquierda o a la derecha. Use números negativos para la alineación izquierda.

O mira http://msdn.microsoft.com/en-us/library/aa331875(v=vs.71).aspx

Solo para agregar a la respuesta de roya. En c # 6.0 ahora puede usar la interpolación de cadenas:

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

Esto realmente puede ser una línea sin todos los dólares adicionales, solo creo que hace que sea un poco más fácil leer de esta manera.

Y también puede usar una importación estática en System.Console, lo que le permite hacer esto:

 using static System.Console; WriteLine(/* write stuff */); 

Lo sé, muy antiguo, pero la solución propuesta no era completamente automática cuando hay cadenas más largas.

Por lo tanto, creé un pequeño método de ayuda que lo hace completamente automático. Simplemente pase en una lista de matriz de cadenas donde cada matriz representa una línea y cada elemento en la matriz, así como un elemento de la línea.

El método se puede usar así:

 var lines = new List(); 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); 

El método de ayuda es el siguiente:

 public static class ConsoleUtility { ///  /// 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 /// List lines, where each line is an array of elements for that line. /// Additional padding between each element (default = 1) ///  public static string PadElementsInLines(List 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(); } } 

Espero que esto ayude a alguien. La fuente es de una publicación en mi blog aquí: http://dev.flauschig.ch/wordpress/?p=387

Puede usar tabs en lugar de espacios entre columnas, y / o establecer el tamaño máximo para una columna en cadenas de formato …

Hay varios paquetes NuGet que pueden ayudar con el formateo. En algunos casos, las capacidades de string.Format son suficientes, pero es posible que desee string.Format automáticamente el tamaño de las columnas en función del contenido, al menos.

ConsoleTableExt

ConsoleTableExt es una biblioteca simple que permite formatear tablas, incluidas tablas sin líneas de cuadrícula. (Un paquete más popular, ConsoleTables , no parece ser compatible con tablas sin bordes .) Aquí hay un ejemplo de cómo formatear una lista de objetos con columnas de tamaño según su contenido:

 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

Si necesita más funciones que eso, cualquier formato de consola se puede lograr con CsConsoleFormat . † Por ejemplo, aquí está el formato de una lista de objetos como una cuadrícula con un ancho de columna fijo de 10, como en las otras respuestas usando una string.Format . 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) }) ) )); 

Puede parecer más complicado que una string.Format pura. string.Format , pero ahora se puede personalizar. Por ejemplo:

  • Si desea AddColumns(10, 10, 10, 10, 10) automáticamente el tamaño de las columnas en función del contenido, reemplace AddColumns(10, 10, 10, 10, 10) con AddColumns(-1, -1, -1, -1, -1) ( -1 es un acceso directo a GridLength.Auto , tiene más opciones de tamaño, incluido el porcentaje del ancho de la ventana de la consola).

  • Si desea alinear las columnas numéricas a la derecha, agregue { Align = Right } al inicializador de la celda.

  • Si desea colorear una columna, agregue { Color = Yellow } al inicializador de la celda.

  • Puede cambiar los estilos de borde y más.

† CsConsoleFormat fue desarrollado por mí.

Realmente me gustan las bibliotecas mencionadas aquí, pero tenía una idea que podría ser más simple que simplemente rellenar o hacer toneladas de manipulaciones de cuerdas,

Puede configurar manualmente su cursor utilizando la longitud máxima de cadena de sus datos. Aquí hay un código para obtener la idea (no probado):

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

podría extrapolar fácilmente si tiene más filas.