从1到10写入数字,将光标位置设置到起始位置,重新开始写入

本文关键字:位置 设置 重新开始 光标 数字 | 更新日期: 2023-09-27 18:17:14

我刚刚看到一种奇怪的行为,我无法解释。我有一个控制台应用程序,它写入从1到9的数字,然后再次将光标设置到控制台窗口的开头。之后,循环继续并重新开始写从1到10的数字。问题是之前写的数字会被覆盖,而不是向前移动。

为了更好地理解我的代码:

int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int counter = 0; counter < 10; counter++)
{
    foreach (int number in numbers)
    {
        Console.Write(number + " ");
        Thread.Sleep(5);
    }
    Console.SetCursorPosition(0, 0);
}

当我在Console.SetCursorPosition(0, 0);下面添加Console.Write("Test");行时,我得到以下输出:

Test1 2 3 4 5 6 7 8 9

我没想到的是:当在下面添加Console.Write(1);时,我得到

1 2 3 4 5 6 7 8 9

我想用我的代码实现以下目标:

1 2 3 4 5 6 7 8 9[现在将光标位置设置到开始位置并向前移动组成数字]1 2 3 4 5 6 7 8 9 1 2 3 4 4 5 6 7 8 9[以此类推]

为什么程序的行为不是这样的?

从1到10写入数字,将光标位置设置到起始位置,重新开始写入

显然,当您将控制台的光标设置为0,0时,您将开始覆盖先前的值,因为这会发生。您可以使用字符串连接轻松地做到这一点,但我建议您使用StringBuilder,因为它是可变的。

    public static void Main(string[] args)
    {
        StringBuilder sb = new StringBuilder();
        int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        for (int counter = 0; counter < 10; counter++)
        {
            StringBuilder numberBuilder = new StringBuilder();
            foreach (int number in numbers)
            {
                numberBuilder.Append(number + " ");
            }
            sb.Insert(0, numberBuilder.ToString());
        }
        Console.WriteLine(sb.ToString());
    }

Here dotnet fiddle example

控制台就像一块画布,一旦写了东西,文本就会被"涂上",直到有东西把它涂上或擦掉。

当你把光标移到开头时,你开始一个字母一个字母地覆盖旧的文本。请看下面的例子

Console.Write("This is some long text");
Console.SetCursorPosition(0, 0);
for(int i = 0; i < 30; i++)
{
    Console.Write("z");
    Thread.Sleep(1000);
}

你可以看到文字以每秒一个字母的速度慢慢地写完。

为了得到你想要的效果,你需要在内存中保存整个字符串的缓冲区并编辑该字符串缓冲区,在你更新缓冲区后,你必须再次写出整行。一个简单的方法来做到这一点是使用StringBuilder作为缓冲区(更新:参见mybirthname的答案例如使用)