【问题标题】:C# Console - hide the input from console window while typingC# 控制台 - 键入时隐藏控制台窗口中的输入
【发布时间】:2014-06-19 11:35:06
【问题描述】:

我使用Console.ReadLine来读取用户的输入。但是,我想在键入时隐藏/排除控制台屏幕上的输入文本。例如,当用户写入“a”时,它会将“a”写入控制台,然后我将有一个值为“a”的变量。但是,我不想在控制台的输出上写“a”。

我该怎么做?

【问题讨论】:

  • Console.ReadLine 的设置方式是将输入直接回显到控制台。对于特殊用例(例如,如果您想输入密码并且不希望人们看到输入的字母),您必须一个接一个地捕获字符(正如@ojblass 指出的那样)并将它们存储到一个变量中你自己。或者,如果您愿意,您可以在控制台的输出中显示一系列“*”,或者如果您愿意,甚至可以用飞猴替换它们。

标签: c# console-application


【解决方案1】:

Console.ReadKey(true) 隐藏用户密钥。我不相信 Console.Read() 提供这样的能力。如有必要,您可以循环阅读一个键,直到按下回车键。示例见this link

【讨论】:

    【解决方案2】:

    这是一个简短的实现。感谢@ojblass 的想法

    System.Console.Write("password: ");
    string password = null;
    while (true)
    {
        var key = System.Console.ReadKey(true);
        if (key.Key == ConsoleKey.Enter)
            break;
        password += key.KeyChar;
    }
    

    【讨论】:

    • 使用 stringbuilder 可能会更好
    • @m4tt1mus 我不同意。 StringBuilder 只是在进行大量字符串连接时提高性能。输入密码不是很多。使用 StringBuilder 只会添加不必要的额外代码。
    • @CathalMF “关于在开始担心性能之前必须连接多少个字符串,人们的意见各不相同。普遍的共识是大约 10 个。” blog.codinghorror.com/…
    • @m4tt1mus 是的,但当我们在每个循环上等待用户输入时不是。它必须是一个完整的循环才有意义。
    • @JustAMartin 与“Ctr+C/Ctrl+V”配合使用。做了一个简短的测试(dotnet core 控制台应用)。
    【解决方案3】:

    我根据dataCore 的答案中的代码和m4tt1mus 的建议创建了这个方法。我还添加了对退格键的支持。

    private static string GetHiddenConsoleInput()
    {
        StringBuilder input = new StringBuilder();
        while (true)
        {
            var key = Console.ReadKey(true);
            if (key.Key == ConsoleKey.Enter) break;
            if (key.Key == ConsoleKey.Backspace && input.Length > 0) input.Remove(input.Length - 1, 1);
            else if (key.Key != ConsoleKey.Backspace) input.Append(key.KeyChar);
        }
        return input.ToString();
    }
    

    【讨论】:

      【解决方案4】:

      我只是在输入密码时将前景色更改为黑色。我是新手,所以这可能是个坏主意,但它对我正在尝试的挑战很有用

      Console.WriteLine("Welcome to our system. Please create a UserName");
              var userName = Console.ReadLine();
              Console.WriteLine("Now please create a password");
              Console.ForegroundColor = ConsoleColor.Black;
              var password = Console.ReadLine();
              Console.ForegroundColor = ConsoleColor.White;
              Console.WriteLine("Okay, let's get you logged in:");
      

      【讨论】:

        【解决方案5】:
        private static string GetPassword()
            {
                StringBuilder input = new StringBuilder();
                while (true)
                {
                    int x = Console.CursorLeft;
                    int y = Console.CursorTop;
                    ConsoleKeyInfo key = Console.ReadKey(true);
                    if (key.Key == ConsoleKey.Enter)
                    {
                        Console.WriteLine();
                        break;
                    }
                    if (key.Key == ConsoleKey.Backspace && input.Length > 0)
                    {
                        input.Remove(input.Length - 1, 1);
                        Console.SetCursorPosition(x - 1, y);
                        Console.Write(" ");
                        Console.SetCursorPosition(x - 1, y);
                    }
                    else if (key.Key != ConsoleKey.Backspace)
                    {
                        input.Append(key.KeyChar);
                        Console.Write("*");
                    }
                }
                return input.ToString();
            }
        

        【讨论】:

          【解决方案6】:

          来自@Fredrik Fjällström 帖子的改进版本: https://stackoverflow.com/a/59668053/2935383

          他的版本很棒,因为您还可以看到光标并在必要时设置密码-*** char。 但仍然缺少的是对不可打印字符的抑制。

              public static string GetPassword()
              {
                  StringBuilder input = new StringBuilder();
                  while (true)
                  {
                      int x = Console.CursorLeft;
                      int y = Console.CursorTop;
                      ConsoleKeyInfo key = Console.ReadKey(true);
                      if (key.Key == ConsoleKey.Enter)
                      {
                          Console.WriteLine();
                          break;
                      }
                      if (key.Key == ConsoleKey.Backspace && input.Length > 0)
                      {
                          input.Remove(input.Length - 1, 1);
                          Console.SetCursorPosition(x - 1, y);
                          Console.Write(" ");
                          Console.SetCursorPosition(x - 1, y);
                      }
                      else if( key.KeyChar < 32 || key.KeyChar > 126 )
                      {
                          Trace.WriteLine("Output suppressed: no key char"); //catch non-printable chars, e.g F1, CursorUp and so ...
                      }
                      else if (key.Key != ConsoleKey.Backspace)
                      {
                          input.Append(key.KeyChar);
                          Console.Write("*");
                      }
                  }
                  return input.ToString();
              }
          

          【讨论】:

            【解决方案7】:

            为了展示与以前的解决方案不同的东西,并看到我喜欢一个好的简单而肮脏的解决方案..

            // Take input character
            val = Console.ReadKey().KeyChar;
            // Remove entered character from console
            Console.Write("\b \b");
            

            显然包裹在一个循环等中。

            我认识的聚会很晚,与其他人相比,这是一个不太优雅的解决方案,但希望这可能对将来的某人有所帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-20
              • 2011-07-19
              • 2019-07-22
              • 2012-10-14
              • 1970-01-01
              相关资源
              最近更新 更多