当在c#中构建Windows控制台应用程序时,是否有可能写入控制台而不必扩展当前行或去到新行?例如,如果我想显示一个百分比,表示一个流程离完成有多近,我只需要在游标所在的同一行上更新该值,而不必将每个百分比放在新行上。
这可以用“标准”c#控制台应用程序来实现吗?
当在c#中构建Windows控制台应用程序时,是否有可能写入控制台而不必扩展当前行或去到新行?例如,如果我想显示一个百分比,表示一个流程离完成有多近,我只需要在游标所在的同一行上更新该值,而不必将每个百分比放在新行上。
这可以用“标准”c#控制台应用程序来实现吗?
当前回答
如果你想让生成的文件看起来很酷,这是可行的。
int num = 1;
var spin = new ConsoleSpinner();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("");
while (true)
{
spin.Turn();
Console.Write("\r{0} Generating Files ", num);
num++;
}
这是我从下面的一些答案得到的方法,并修改了它
public class ConsoleSpinner
{
int counter;
public void Turn()
{
counter++;
switch (counter % 4)
{
case 0: Console.Write("."); counter = 0; break;
case 1: Console.Write(".."); break;
case 2: Console.Write("..."); break;
case 3: Console.Write("...."); break;
case 4: Console.Write("\r"); break;
}
Thread.Sleep(100);
Console.SetCursorPosition(23, Console.CursorTop);
}
}
其他回答
来自MSDN的控制台文档:
您可以通过设置 TextWriter。属性的NewLine 属性转移到另一行 终止的字符串。例如, c#语句,Console.Error.NewLine = “\r\n\r\n”;,设置行终止 字符串用于标准错误输出 流到两车厢返回并行 饲料序列。然后你就可以 显式调用WriteLine方法 错误输出流对象的 在c#语句中, Console.Error.WriteLine ();
所以,我这样做了:
Console.Out.Newline = String.Empty;
然后我就可以自己控制输出了;
Console.WriteLine("Starting item 1:");
Item1();
Console.WriteLine("OK.\nStarting Item2:");
另一种方法。
这是另一个选项:D
class Program
{
static void Main(string[] args)
{
Console.Write("Working... ");
int spinIndex = 0;
while (true)
{
// obfuscate FTW! Let's hope overflow is disabled or testers are impatient
Console.Write("\b" + @"/-\|"[(spinIndex++) & 3]);
}
}
}
在行首显式地使用Carrage Return (\r),而不是(隐式或显式地)在行尾使用New line (\n),应该得到你想要的结果。例如:
void demoPercentDone() {
for(int i = 0; i < 100; i++) {
System.Console.Write( "\rProcessing {0}%...", i );
System.Threading.Thread.Sleep( 1000 );
}
System.Console.WriteLine();
}
SetCursorPosition方法适用于多线程场景,而其他两个方法则不能
如果要更新一行,但信息太长而不能在一行上显示,则可能需要一些新行。我遇到过这个问题,下面是解决这个问题的一种方法。
public class DumpOutPutInforInSameLine
{
//content show in how many lines
int TotalLine = 0;
//start cursor line
int cursorTop = 0;
// use to set character number show in one line
int OneLineCharNum = 75;
public void DumpInformation(string content)
{
OutPutInSameLine(content);
SetBackSpace();
}
static void backspace(int n)
{
for (var i = 0; i < n; ++i)
Console.Write("\b \b");
}
public void SetBackSpace()
{
if (TotalLine == 0)
{
backspace(OneLineCharNum);
}
else
{
TotalLine--;
while (TotalLine >= 0)
{
backspace(OneLineCharNum);
TotalLine--;
if (TotalLine >= 0)
{
Console.SetCursorPosition(OneLineCharNum, cursorTop + TotalLine);
}
}
}
}
private void OutPutInSameLine(string content)
{
//Console.WriteLine(TotalNum);
cursorTop = Console.CursorTop;
TotalLine = content.Length / OneLineCharNum;
if (content.Length % OneLineCharNum > 0)
{
TotalLine++;
}
if (TotalLine == 0)
{
Console.Write("{0}", content);
return;
}
int i = 0;
while (i < TotalLine)
{
int cNum = i * OneLineCharNum;
if (i < TotalLine - 1)
{
Console.WriteLine("{0}", content.Substring(cNum, OneLineCharNum));
}
else
{
Console.Write("{0}", content.Substring(cNum, content.Length - cNum));
}
i++;
}
}
}
class Program
{
static void Main(string[] args)
{
DumpOutPutInforInSameLine outPutInSameLine = new DumpOutPutInforInSameLine();
outPutInSameLine.DumpInformation("");
outPutInSameLine.DumpInformation("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
outPutInSameLine.DumpInformation("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
outPutInSameLine.DumpInformation("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
//need several lines
outPutInSameLine.DumpInformation("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
outPutInSameLine.DumpInformation("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
outPutInSameLine.DumpInformation("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
outPutInSameLine.DumpInformation("bbbbbbbbbbbbbbbbbbbbbbbbbbb");
}
}