如何在不创建新行的情况下更新 Console.WriteLine 中的循环结果?
How to update for loop result in Console.WriteLine without creating new line?
此代码显示如下结果:
distance from target : 10
distance from target : 9
distance from target : 8
(line by line)
我想显示结果 - 与目标的距离:10,然后 9,8,7 替换 10 的位置,(只有 10 的位置会更新)
public void Attack()
{
for (int i = 1; i < 3; i++)
{
if (i == 1)
{
Console.WriteLine("Target Locked (+)");
Thread.Sleep(2000);
}
if (i == 2)
{
Console.WriteLine("Fired!");
Thread.Sleep(1000);
}
}
Random random = new Random();
int distance = random.Next(100, 3000);
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("BloooW!");
}
那么你应该先删除写入控制台的距离,可以用一个或多个退格键来完成\b
改变
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
至
int lastDistanceLength = 0; // save the last number of distance chars written
for (int i = distance; i > 0; i = i - 3)
{
if(lastDistanceLength == 0) { // no distance chars written yet.
Console.Write("distance from target : " + i);
}
else {
for(int j=0;j‹lastDistanceLength;j++)
Console.Write("\b"); // delete old distance
Console.Write(""+i);
}
lastDistanceLength = i==10 ? 2 : 1;
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("\r\nBloooW!");
您很可能需要更高级的算法来计算 lastDistanceLength,也许只需将 i 转换为字符串并获取长度,例如lastDistanceLength = (""+i).Length
这里有一个比较全面的解释:Is there a way to delete a character that has just been written using Console.WriteLine?
您可以像这样使用 Console.CursorTop :
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i + " "); // dirty trick to erase longer previous numbers
Thread.Sleep(30);
Console.CursorTop--;
}
Console.CursorTop++; // so that we advance to the next line after the loop.
它将光标向上移动一行,因此后续调用会覆盖之前在上面一行中的内容。
这种方法不是最有效的方法,因为它会重写整行,但它很简单,而且从用户的角度来看,只会更新数值。
如果如此小的性能差异很重要,您可以尝试将光标位置更精确地设置为数值开始的位置。我不确定是否可行,但如果重要的话值得一试。
您可以将 Console.WriteLine
更改为 Console.Write
在字符串的前面添加一个 \r
:
for (int i = distance; i > 0; i = i - 3)
{
Console.Write("\rdistance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("");
这将导致控制台 return 到行的开头并再次写入字符串以覆盖上次写入时的字符串。还要确保在 for 循环之后添加一个 Console.WriteLine("");
以移动到下一行,这样您的下一次写入就不会从该行开始。
如果您的字符串只会变得更长,则此解决方案最有效。
如果您的字符串要变短,您可以在字符串末尾添加一些白色 space,如下所示:
Console.Write("\rdistance from target : {0} ", i);
当你从 10
到 9
时,你就是这种情况
您可以使用 CursorTop、CursorLeft 和 SetCursorPosition 来精确控制写入输出的位置。但真正的诀窍是删除你以前在那个地方写的东西。在这里您可以使用控制台的格式字符串功能。Write/WriteLine
// This needs to be written just one time
Console.Write("distance from target : ");
// Now get the current cursor position after the write above
int posX = Console.CursorLeft;
int posY = Console.CursorTop;
for (int i = distance; i > 0; i = i - 3)
{
// Position the cursor where needed
Console.SetCursorPosition(posX, posY);
// Replace the previous write with a number aligned on the left on 4 spaces
Console.Write($"{i,-4:D}");
// As an alternative to SetCursorPosition you could have
// Console.CursorLeft -= 4;
// but, to me this is less clear....
Thread.Sleep(30);
}
// Do not forget to jump to the next line
Console.WriteLine("\r\nBloooW!");
此代码显示如下结果:
distance from target : 10
distance from target : 9
distance from target : 8
(line by line)
我想显示结果 - 与目标的距离:10,然后 9,8,7 替换 10 的位置,(只有 10 的位置会更新)
public void Attack()
{
for (int i = 1; i < 3; i++)
{
if (i == 1)
{
Console.WriteLine("Target Locked (+)");
Thread.Sleep(2000);
}
if (i == 2)
{
Console.WriteLine("Fired!");
Thread.Sleep(1000);
}
}
Random random = new Random();
int distance = random.Next(100, 3000);
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("BloooW!");
}
那么你应该先删除写入控制台的距离,可以用一个或多个退格键来完成\b
改变
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
至
int lastDistanceLength = 0; // save the last number of distance chars written
for (int i = distance; i > 0; i = i - 3)
{
if(lastDistanceLength == 0) { // no distance chars written yet.
Console.Write("distance from target : " + i);
}
else {
for(int j=0;j‹lastDistanceLength;j++)
Console.Write("\b"); // delete old distance
Console.Write(""+i);
}
lastDistanceLength = i==10 ? 2 : 1;
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("\r\nBloooW!");
您很可能需要更高级的算法来计算 lastDistanceLength,也许只需将 i 转换为字符串并获取长度,例如lastDistanceLength = (""+i).Length
这里有一个比较全面的解释:Is there a way to delete a character that has just been written using Console.WriteLine?
您可以像这样使用 Console.CursorTop :
for (int i = distance; i > 0; i = i - 3)
{
Console.WriteLine("distance from target : " + i + " "); // dirty trick to erase longer previous numbers
Thread.Sleep(30);
Console.CursorTop--;
}
Console.CursorTop++; // so that we advance to the next line after the loop.
它将光标向上移动一行,因此后续调用会覆盖之前在上面一行中的内容。
这种方法不是最有效的方法,因为它会重写整行,但它很简单,而且从用户的角度来看,只会更新数值。
如果如此小的性能差异很重要,您可以尝试将光标位置更精确地设置为数值开始的位置。我不确定是否可行,但如果重要的话值得一试。
您可以将 Console.WriteLine
更改为 Console.Write
在字符串的前面添加一个 \r
:
for (int i = distance; i > 0; i = i - 3)
{
Console.Write("\rdistance from target : " + i);
Thread.Sleep(30);
//Console.Clear();
}
Console.WriteLine("");
这将导致控制台 return 到行的开头并再次写入字符串以覆盖上次写入时的字符串。还要确保在 for 循环之后添加一个 Console.WriteLine("");
以移动到下一行,这样您的下一次写入就不会从该行开始。
如果您的字符串只会变得更长,则此解决方案最有效。
如果您的字符串要变短,您可以在字符串末尾添加一些白色 space,如下所示:
Console.Write("\rdistance from target : {0} ", i);
当你从 10
到 9
您可以使用 CursorTop、CursorLeft 和 SetCursorPosition 来精确控制写入输出的位置。但真正的诀窍是删除你以前在那个地方写的东西。在这里您可以使用控制台的格式字符串功能。Write/WriteLine
// This needs to be written just one time
Console.Write("distance from target : ");
// Now get the current cursor position after the write above
int posX = Console.CursorLeft;
int posY = Console.CursorTop;
for (int i = distance; i > 0; i = i - 3)
{
// Position the cursor where needed
Console.SetCursorPosition(posX, posY);
// Replace the previous write with a number aligned on the left on 4 spaces
Console.Write($"{i,-4:D}");
// As an alternative to SetCursorPosition you could have
// Console.CursorLeft -= 4;
// but, to me this is less clear....
Thread.Sleep(30);
}
// Do not forget to jump to the next line
Console.WriteLine("\r\nBloooW!");