当输出到控制台时,您可以设置光标的特定位置并写入(或者使用其他漂亮的技巧,例如打印退格将带您回来。)
是否可以通过文本流完成类似的事情?
场景:我需要构建一个包含n
个文本的字符串,其中每个文本可能位于不同的行和起始位置(或左上角和左上角)。
两个字符串可能出现在同一行上。
我可以用它构建一个简单的Dictionary<int, StringBuilder>
和fidget,但是我想知道是否有类似于文本流的控制台功能,你可以写到特定的地方(行)和专栏)。
修改 这仅适用于文本。没有控制权 结果可能是一个包含多个新行的字符串,并且文本出现在不同的位置。
示例(.
将为空格):
..... txt3....... txt2
......................
................ txt1.
这将是{3}列(无论如何)txt1
,txt2
和txt3
以及行1具有不同列值的结果(txt3
列&lt; txt2
colmun)
答案 0 :(得分:1)
在等待更好的答案时,这是我的解决方案。似乎工作,经过轻微测试,可以简单地粘贴到linqpad并运行。
void Main()
{
m_dict = new SortedDictionary<int, StringBuilder>();
AddTextAt(1,40, "first");
AddTextAt(2,40, "xx");
AddTextAt(0,10, "second");
AddTextAt(4,5, "third");
AddTextAt(1,15, "four");
GetStringFromDictionary().Dump();
}
// "global" variable
SortedDictionary<int, StringBuilder> m_dict;
/// <summary>
/// This will emulate writting to the console, where you can set the row/column and put your text there.
/// It's done by having Dictionary(int,StringBuilder) that will use to store our data, and eventually,
/// when we need the string iterate over it and build our final representation.
/// </summary>
private void AddTextAt(int row, int column, string text)
{
StringBuilder sb;
// NB: The following will initialize the string builder !!
// Dictionary doesn't have an entry for this row, add it and all the ones before it
if (!m_dict.TryGetValue(row, out sb))
{
int start = m_dict.Keys.Any() ? m_dict.Keys.Last() +1 : 0;
for (int i = start ; i <= row; i++)
{
m_dict.Add(i, null);
}
}
int leftPad = column + text.Length;
// If dictionary doesn't have a value for this row, just create a StringBuilder with as many
// columns as left padding, and then the text
if (sb == null)
{
sb = new StringBuilder(text.PadLeft(leftPad));
m_dict[row] = sb;
}
// If it does have a value:
else
{
// If the new string is to be to the "right" of the current text, append with proper padding
// (column - current string builder length) and the text
int currrentSbLength = sb.ToString().Length;
if (column >= currrentSbLength)
{
leftPad = column - currrentSbLength + text.Length;
sb.Append(text.PadLeft(leftPad));
}
// otherwise, text goes on the "left", create a new string builder with padding and text, and
// append the older one at the end (with proper padding?)
else
{
m_dict[row] = new StringBuilder( text.PadLeft(leftPad)
+ sb.ToString().Substring(leftPad) );
}
}
}
/// <summary>
/// Concatenates all the strings from the private dictionary, to get a representation of the final string.
/// </summary>
private string GetStringFromDictionary()
{
var sb = new StringBuilder();
foreach (var k in m_dict.Keys)
{
if (m_dict[k]!=null)
sb.AppendLine(m_dict[k].ToString());
else
sb.AppendLine();
}
return sb.ToString();
}
输出:
second
four first
xx
third
答案 1 :(得分:0)
没有。文本文件实际上没有水平/垂直位置的概念,因此您需要自己构建某种定位。
对于基本定位标签("\t"
)可能就足够了,对于任何更高级的标签,您需要用空格填充空白区域。
听起来你有某种表布局 - 首先在单元格中构建数据可能更容易(List<List<string>>
- 由字符串列组成的行列表),而不是用{{1}格式化它或者为每个“单元格”手动添加必要数量的空格