等待输入时写入控制台

时间:2018-11-16 14:34:12

标签: c# loops user-input

我是编程的初学者,我需要编写一个c#控制台应用程序,该应用程序在循环中执行某些操作(假设在控制台中写星号),直到用户输入诸如“停止”的命令为止。 像这样:

While !('user entered word "stop"'){
    Console.Write("*")
}

该程序应独立于任何用户按键或其他命令来写星号,直到用户准确输入“停止”并按Enter时它才起作用。 这个:

string userinput = "";
while (true){
     Console.Write("*");
     userinput = Console.ReadLine();
     if(userinput == "stop"){
         break;
     }
}

不是解决方案,因为它将在打印每颗星星后不断询问用户输入的信息。

很抱歉,如果这是一个愚蠢的问题,我什至不知道从哪里开始。

编辑: 好的,这可能是另一项任务,例如复制文件或播放音乐或其他任何东西。我只是不明白如何不断检查控制台的 在不询问用户的情况下输入了停用词。控制台可以为空,等待用户输入。

5 个答案:

答案 0 :(得分:0)

如果使用控制台同时打印星星,他将在何处写入输入。 您可以循环打印星号,直到未按下键盘上的特定按钮。 之后,您可以进行逻辑处理以将按下的键保存到变量并循环,直到未编写特定的组合。不要忘记将“睡眠”置于您的循环中。 无论如何,同时写星星和输入信息不是一个好主意。

答案 1 :(得分:0)

这将在用户按下任何键时停止

        while (!Console.KeyAvailable)
        {
            Console.Write("*");
        }

仅当用户按下Escape键时,此操作才会停止:

        while (true)
        {
            Console.Write("*");

            if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.Escape)
            {
                break;
            }
        }

如果您希望用户必须键入多个字母(如“停止”),则必须阅读他们按下的所有键,并检查最后四个键是否为“停止”。

答案 2 :(得分:0)

在不锁定主线程的情况下读取输入good answer here。您可以在单独的线程中使用Console.KeyAvailableConsole.ReadKey()

同时写回控制台比较麻烦。如果您让用户键入盲点(这样他们就看不到他们键入的内容),这会更容易。但是问题开始于您想向用户显示他们键入的内容,因为您必须自己将用户输入写回到控制台(因为您不能使用Console.ReadLine()来完成操作)给你)。而且,我想,您不想在输入的中间出现星星,例如:

s*****t***o**p

我认为您想要更多类似的东西:

***********
stop

这意味着您需要在控制台中四处移动光标,以在一行上写星星,而在另一行上写用户输入。

您应该可以使用Console.SetCursorPosition来执行此操作,以根据要在哪一行上写光标来上下移动光标。但是,您还必须跟踪到目前为止每行写了多少个字符。

答案 3 :(得分:0)

您可以使用多线程来实现此目的。这样,主线程启动了一个后台线程,该线程将写星号,直到该人员键入停止并按Enter键为止。但是,它可能会影响它的显示方式,因为在您键入时,它看起来像是自动将星号添加到您按下的键上,而不必担心,这取决于您的计时器。当您按Enter键时,它将不会读取以前添加的星号。

下面是示例代码,可帮助您实现所需的目标。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    namespace Practice
{
    class Program
    {
        static bool write = true;
        static void Main(string[] args)
        {
            //Write the stars using a background thread
            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                WriteStars();
            }).Start();

            while (true)
            {
                //Read the user input
                var input = Console.ReadLine();
                //Check the user input
                if (input.Equals("stop", StringComparison.OrdinalIgnoreCase))
                {
                    write = false;
                    Console.WriteLine("Finished. Program stopped!");
                    Console.ReadKey();
                    break;
                }
            }
        }

        private static void WriteStars()
        {
            while (write)
            {
                Console.Write("*");

                //Make the thread wait for half a second
                Thread.Sleep(500);
            }
        }
    }
}

谢谢

答案 4 :(得分:0)

这是一个非常复杂的解决方案。它不是在寻找“停止”一词,只是在提示输入一个字符串(任何字符串)。不过,这很容易适应。

它每250毫秒对键盘进行一次轮询,以获取按键输入。如果两秒钟没有输入,它将输出一个星号。输入字符(或退格键)时,它会写出整行(在右边用空格填充),而将现有的星号空白。

它不需要处理的一件事就是换行。如果足够长的时间使该行用星号填充,那么控制台将换行到第二行,并且这些星号将永远不会消失。

我很惊讶,但这实际上感觉像是一个合理的UI。我不确定是否值得增加复杂性,但是...

  public static string GetString(string prompt)
  {
      const int pollTime = 250;       //milliseconds
      const int starTime = 8;         //pollTime quantums (in this case 2 * 250 = 2000 ms)
      string buffer = string.Empty;
      Console.Write($"{prompt}: ");
      var top = Console.CursorTop;
      var left = Console.CursorLeft;
      //two loops, 
      //outer loop is per character
      //the inner one causes a star to be output every 2 seconds, 
      //it causes the keyboard to be polled every 1/4 second
      while (true)        //this loop breaks with a return statement
      {
          var noChar = true;
          var starLoopCount = 0;
          while (noChar && starLoopCount < starTime)
          {
              if (Console.KeyAvailable)
              {
                  var keyRead = Console.ReadKey();
                  if (keyRead.Key == ConsoleKey.Enter)
                  {
                      OutputLine(left, top, buffer);
                      return buffer;
                  }

                  if (keyRead.Key == ConsoleKey.Backspace)
                  {
                      if (buffer.Length > 0)
                      {
                          buffer = buffer.Substring(0, buffer.Length - 1);
                          OutputLine(left, top, buffer);
                          noChar = false;
                          continue;
                      }
                  }
                  //otherwise, add the key to the buffer
                  buffer += keyRead.KeyChar;
                  OutputLine(left, top, buffer);
                  noChar = false;
                  starLoopCount = 0;
              }
              ++starLoopCount;
              Thread.Sleep(pollTime);
          }

          if (noChar)
          {
              Console.Write("*");
          }
      }
  }

  private static void OutputLine(int left, int top, string line)
  {
      Console.SetCursorPosition(left, top);
      var blank = new string(' ', 80 - left - line.Length);
      Console.Write(line + blank);
      Console.SetCursorPosition(left + line.Length, top);
  }