• 怎样在控制台里面输入密码的时候显示*


     

             或许大家觉得都很简单,一开始我也觉得没什么,不过学生的一个问题,让我觉得有点东西可写!

             传智播客.Net基础班915日的学员问道:“怎样在控制台里面输入密码的时候显示*”。虽然当时很快解决了,不过怎么写的有些学生会更关心。

             我在传智播客教C#基础,主要针对没有基础、没有学过编程的学员来编写课程内容,我常常说基础班要掌握的只有两点:

             第一、面向对象编程思想的理解

             第二、如何写出程序

     

             今天不打算讨论第一个问题,主要说说第二个吧!

             “老师讲的都听得懂,但是自己写就是不会… …”我想大多数学习编程的同学都有这样的问题,所以对于今天学生的这个问题,我把我的分析过程写一下。

     

             首先我本身没有写过代码实现这个功能,但是学生问到了,需要看看用什么样的代码能最简单的做出来,首先对于按下键盘,已经熟悉的方法有两个

        Console.ReadLine();
    Console.ReadKey();

     

             但是对于Console.ReadLine()我们了解是针对一行代码,也就是说当按下回车的时候,才会有变化,那么Console.ReadKey()怎么样呢?

     

    我新建一个项目,键入代码

    class Program
    {
    static void Main(string[] args)
    {
      System.Console.ReadKey();
      System.Console.ReadKey();
    }
    }

    编译运行,等待按下两个键,我们发现按下的键也会在屏幕上显示,那怎么显示*呢?

     

             思考发现按下总会有文字,那要显示别的,不显示文字怎么办?其实和“冒名顶替”倒还是有点像,比如上学的时候“带喊到”的现象大家还是比较清楚地,比如喊道“张三”,但是张三和李四打了招呼,那么李四会帮忙喊到。想想这不就是一样的嘛!

             当按下按键的时候,计算机不显示按键(肯定是先通知了嘛),然后由Console.Write()方法在屏幕上显示一个*,没按一次,显示一个,这样不就好了吗!OK那么思路是有了,下面理一理。

     

    步骤可以简化为

    -> 首先提示用户输入密码

    -> 然后提供输入,但是只记录按下的键,不显示

    -> 然后每次按下一个键,输出一个*

    那么这里会发现只能输入一个字符,还是不好,那怎么处理可是多次输入,并且按照习惯回车表示结束呢?

             用循环,并当按下回车表示结束,那么可以修改一下上面的步骤

    -> 首先提示用户输入密码

    -> 写一个循环

    -> 然后提供输入,但是只记录按下的键,不显示

    -> 然后每次按下一个键,输出一个*

    -> 当按下回车跳出循环

    那么可以修改我们的项目

    class Program
    {
    static void Main(string[] args)
    {
    System.Console.WriteLine(“请输入密码”);
    while(true)
         {
        
    if(如果输入回车)
           {
          
    break;
           }
           记录按下的键,但是不显示;
           System.Console.Write(“
    *”);
        }
       }
    }

    用伪代码来实现会一开始写代码轻松许多,但是问题是现在怎么知道我按下的是回车呢?并且怎么才能接收按下一个字符不显示呢?我们接收一个字符只学习了Console.ReadKey(),而刚刚实验了,也是会显示出按下的键啊?

             那么这时既然没有办法了,查看MSDN吧!

             MSDN很强大,只要这么写Console.ReadKey(true)就不会显示按下的任何信息了,并且知道返回按下的Unicode编码,但是Unicode编码又是什么?这里还不知道,但是既然返回,我就找个变量接收。

             了解到Console.ReadKey()返回的类型是ConsoleKeyInfo,那么可以修改一下代码

    class Program
    {
    static void Main(string[] args)
    {
    System.Console.WriteLine(“请输入密码”);
    while(true)
        {
        ConsoleKeyInfo temp
    = System.Console.ReadKey(true);
        
    if(如果输入回车)
          {
          
    break;
          }
          记录按下的键,但是不显示;
          System.Console.Write(“
    *”);
        }
      }
    }

    那么可以记录按下的信息了。但是怎么用呢?试了几次都报错,没办法?先点点看。

    key后面加一个“.”会发现一个单词KeyChar,很兴奋,这个就是字符嘛!但是仍然疑虑,那么我们调试一下,在VS里设下断点

    这么一来运行到这里,可以看看temp里面的值是多少。

    很好,可以看到这里按下回车后,temp里面会记录下来,并且KeyChar里面就是对应的字符,修改代码

    using System;
    class Program
    {
    static void Main(string[] args)
      {
      Console.WriteLine(“请输入密码”);
      
    while(true)
        {
        ConsoleKeyInfo temp
    = Console.ReadKey(true);
        
    if(temp.KeyChar == ‘\r’)
          {
          
    break;
          }
          记录按下的键,但是不显示;
          System.Console.Write(“
    *”);
        }
      }
    }

    这么一来,只要按下回车就结束了。下面在定义一个字符串,将按下的键记录下来

    using System;
    class Program
    {
    static void Main(string[] args)
      {
      
    string pwd = “”;
      Console.WriteLine(“请输入密码”);
      
    while(true)
        {
        ConsoleKeyInfo temp
    = Console.ReadKey(true);
        
    if(temp.KeyChar == ‘\r’)
          {
          
    break;
          }
          pwd
    += temp.KeyChar.ToString();
          System.Console.Write(“
    *”);
        }
        Console.WriteLine(“\n输入成功,你输入的密码是{
    0}”,pwd);
        Console.ReadKey();
      }
    }

    这么一来就OK了,但是用一用又有一个问题,输入错误退格的时候会出现错误

     

             利用设断点的方法可以知道,当按下“退格”键时,Console.ReadKey()中返回了’\b’那么这时怎么实现退格呢?

             我们用现实的方式模拟一下,假设有一行字符串”abcdefg”,显示的是”*******”

             当按下退格键的时候,应该将显示的7*改为6个,光标并停留在第六个后面,并且里面的字符串只能是”abcdef”

             先来看怎么实现去掉一个*,毫无疑问,在控制台中去掉*是不可能的,要么清屏,要么用一个字符去覆盖原有的。这里如果采用第二种方式,也就只有用空格了,那么只需要退一格,输出一个空格,然后再退一格。那么可以添加逻辑

    if(temp.KeyChar == ‘\b’)
    {
    System.Console.Write(“\b \b”);
    }

    然后就剩下修改存储的字符串了,很简单,只要取出第零个到倒数第二个的即可,因此

    if(temp.KeyChar == ‘\b’)
    {
    System.Console.Write(“
    *”);
    pwd
    = pwd.Substring(0, pwd.Length - 1);
    }

    这里还需要考虑,如果没有输入任何内容,键入退格,应该改不做任何操作,所以还需要添加代码

    if(pwd.Length == 0 && temp.KeyChar == ‘\b’)
    {
    continue;
    }

    整合一下代码,就是

    using System;
    class Program
    {
    static void Main(string[] args)
      {
      Console.WriteLine(“请输入密码”);
      
    string pwd = “”;
      
    while(true)
        {
        // ConsoleKeyInfo temp
    = Console.ReadKey(); 这行代码有笔误,在此修改20110920
          ConsoleKeyInfo temp = Console.ReadKey(true);
        
    if(temp.KeyChar == ‘\b’ && pwd.Length == 0)
          {
          
    continue;
          }
          if(temp.KeyChar == ‘\r’)
          {
          
    break;
          }
          if(temp.KeyChar == ‘\b’)
          {
          Console.Write(“\b \b”);
          pwd
    = pwd.Substring(0, pwd.Length - 1);
          }
          else
          {
          pwd
    += temp.KeyChar.ToString().Trim();
          Console.Write(“
    *”);
          }
        }
        // 显示出来填入的密码
        Console.WriteLine(“您输入的密码是{0}”, pwd);
        Console.ReadKey();
      }
    }

     

    这样就大功告成!偶也!

    实际上这段代码还是不好,还有可以优化一下,代码有些冗余,不过对于初学者,这个先练着!












  • 相关阅读:
    火炬之光模型导出(Unity载入火炬之光的模型)
    树的左旋与右旋
    javaEE开发之导出excel工具类
    STL algorithm算法is_permutation(27)
    学做衣服论坛 -服装DIY教程,缤纷服装网,裁剪教程,家用缝纫机,买布料
    傲娇_百度百科
    《失败不是成功之母》阅读理解
    失败是不是成功之母
    正则表达式多语种的web版本
    date tod = boost::gregorian::day_clock::local_day(); //当前日期
  • 原文地址:https://www.cnblogs.com/jiangkun86/p/2181910.html
Copyright © 2020-2023  润新知