如何使用 Console.WriteLine 对齐列中的文本?
Posted
技术标签:
【中文标题】如何使用 Console.WriteLine 对齐列中的文本?【英文标题】:How can I align text in columns using Console.WriteLine? 【发布时间】:2011-05-25 20:13:35 【问题描述】:我有一种列显示,但最后两列似乎没有正确对齐。这是我目前拥有的代码:
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);
【问题讨论】:
See here 获取此问题的更通用版本。那里的答案也值得一试。 【参考方案1】:对齐可以与字符串插值结合,放在':'格式字符前面。
Console.WriteLine($"name,40 MaterialArea,10:N2m² MaterialWeightInLbs,10:N0lbs Cost,10:C2");
【讨论】:
【参考方案2】:做一些填充,即
public static void prn(string fname, string fvalue)
string outstring = fname.PadRight(20) +"\t\t " + fvalue;
Console.WriteLine(outstring);
这很好,至少对我来说。
【讨论】:
【参考方案3】:我真的很喜欢这里提到的那些库,但我有一个想法,它可能比仅仅填充或进行大量字符串操作更简单,
您可以使用数据的最大字符串长度手动设置光标。这里有一些代码来得到这个想法(未经测试):
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]);
如果您有更多行,您可以轻松推断。
【讨论】:
【参考方案4】:有几个 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 的网格,就像在其他答案中使用 @ 987654326@:
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
更复杂,但现在可以自定义。例如:
如果要将数字列向右对齐,请将 Align = Right
添加到单元格的初始化程序中。
如果要为列着色,请将 Color = Yellow
添加到单元格的初始化程序中。
您可以更改边框样式等等。
† CsConsoleFormat 是我开发的。
【讨论】:
【参考方案5】:只是为了添加到 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 */);
【讨论】:
msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspx 有关于“对齐”的文档。很有帮助! 要左对齐,然后使用这样的负数:$"thirtyPercentValue,-10"
。【参考方案6】:
我知道,很老的线程,但是当周围有更长的字符串时,建议的解决方案不是全自动的。
因此,我创建了一个完全自动化的小型辅助方法。只需传入一个字符串数组列表,其中每个数组代表一条线,数组中的每个元素,以及线的一个元素。
方法可以这样使用:
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
部分。只需在 foreach 末尾执行 sb.AppendLine();
即可。【参考方案7】:
试试这个
Console.WriteLine("0,101,102,103,104,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
【讨论】:
其实你不需要传递 string.format 方法。换句话说,这将是同样的事情:Console.WriteLine("0,101,102,103,104,10", customer[DisplayPos], sales_figures[DisplayPos], fee_payable[DisplayPos], seventy_percent_value, thirty_percent_value);
【参考方案8】:
您应该将实际的制表符(\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);
【讨论】:
只有当您的数据长度相似时,选项卡才能正常工作。如果您有不同长度的数据,您应该使用带有格式字符串的 royas 答案。 是的,他的答案要好得多。我一看到它就投了赞成票,但留下了我的,以防万一更简单的方法更有效。不过,我不确定为什么我的被接受了... :-) 别忘了 string.PadRight() 和 string.PadLeft() 如果您尝试将文本与可变字体宽度对齐,royas 的回答没有帮助。我认为您需要将填充与this answer 中的选项卡结合使用。【参考方案9】:您可以使用制表符代替列之间的空格,和/或在格式字符串中设置列的最大大小...
【讨论】:
以上是关于如何使用 Console.WriteLine 对齐列中的文本?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Console.WriteLine() 多次打印相同的字符 [重复]
如何包含行号和文件名 Console.WriteLine 输出? [复制]