在使用try parse时如何检查变量是否与另一个变量相等?

时间:2016-11-11 14:26:01

标签: c#

我制作了一个程序来检查用户引脚是否正确,但只检查引脚是否为整数。无论如何,通过仅使用1个while循环来使这个代码更有效吗?

int pin;
int realPin = 1111;
Console.Write("What's the pin: ");
while(!int.TryParse(Console.ReadLine(), out pin)){
    Console.Write("Please enter a 4 numbers please: ");
}
while(pin != realPin){
    Console.Write("Wrong Password: ");
    while(!int.TryParse(Console.ReadLine(), out pin)){
        Console.Write("Please enter 4 numbers please: ");
    }
}

5 个答案:

答案 0 :(得分:1)

当您发现自己编写重复代码时,应考虑将重复代码移动到可以重复使用的新方法:

public static void Main()
{
    int realPin = 1111;

    Console.Write("What's the pin: ");

    var pin = GetUserInput();
    while (pin != realPin)
    {
        Console.Write("Wrong Password: ");
        pin = GetUserInput();
    }
}

public static int GetUserInput()
{
    int pin;
    while (!int.TryParse(Console.ReadLine(), out pin))
    {
        Console.Write("Please enter a 4 numbers please: "
    }

    return pin;
}

代码在性能方面效率不高,但它以更干燥的方式考虑

答案 1 :(得分:1)

我建议分离语法错误(例如bla-bla-bla输入)和错误的密码尝试1234

  int realPin = 1111;

  while (true) {
    int pin; 

    do {
      Console.WriteLine("Please enter a 4 numbers please: ");
    }
    while (!int.TryParse(Console.ReadLine(), out pin)); 

    if (pin == realPin)
      break;

    Console.WriteLine("Wrong Password");
  }

  // unlocked

但是,您可以将它们组合到单个循环中:

  int realPin = 1111;
  int pin;

  do {
    Console.WriteLine("Please enter a 4 numbers please: ");
  }
  while (!int.TryParse(Console.ReadLine(), out pin) || (pin != realPin));

  // unlocked

答案 2 :(得分:1)

您实际上根本不需要将值转换为整数,比较字符串更容易,因此您可能会回退到执行单个测试。这也意味着,000001111之类的输入不会被接受,这似乎是有效的,因为您的问题与PIN验证有关。

以下是我如何做你已经概述的内容:

    /// <summary>
    /// Slightly over-engineered :)
    /// </summary>
    /// <param name="args"></param>
    public static void Main(string[] args)
    {
        string rawInput;
        while (true)
        {
            rawInput = ReadPin();

            // No need to attempt parsing to an integer, as the PIN isn't stored as an integer
            bool isValid = Securityish.ValidatePin(rawInput);

            // If user has entered a valid PIN, break out of the loop ...
            if (isValid)
                break;

            // ... otherwise let them know that they're entered an invalid or incorrect PIN
            Console.WriteLine("That value is incorrect...");
        }

        Console.WriteLine("Unlocked, press any key to continue");
        Console.Read();
    }

    /// <summary>
    /// Reads user input and masks to prevent accidental disclosure of the user's PIN
    /// </summary>
    /// <returns></returns>
    public static string ReadPin()
    {
        Console.Write("Please enter your PIN: ");

        string input = "";
        while (true)
        {
            // Read all key presses
            ConsoleKeyInfo key = Console.ReadKey();

            // If user has pressed enter, it's time to return the accumulated input, so bust out of this loop
            if (key.Key == ConsoleKey.Enter)
            {
                break;
            }

            if (key.Key == ConsoleKey.Backspace)
            {
                // Allow deletion of PIN characters
                if (input.Length > 0)
                {
                    Console.Write(" \b");
                    input = input.Substring(0, input.Length - 1);
                }
                else
                {
                    // The last character is a space, just put it back again then wait for further input
                    Console.Write(" ");
                }

                continue;
            }

            // Function keys etc. return a null character
            if (key.KeyChar == '\0')
            {
                // Overwrite with a blank character, then move backwards to where we were in the first place
                Console.Write("\b \b");
                continue;
            }

            input += key.KeyChar;

            // Mask input
            Console.Write("\b*");
        }

        // Add blank line to keep input clean
        Console.WriteLine();
        return input;
    }
}

internal static class Securityish
{
    /// <summary>
    /// Compares a supplied value against a secret PIN and returns whether the values match
    /// </summary>
    /// <param name="pin"></param>
    /// <returns></returns>
    internal static bool ValidatePin(string pin)
    {
        // Might be better to use one way hashing here
        return pin != null && pin.Equals(UnlockCode);
    }

    // TODO: Make this read a value from file, database, somewhere
    private static string UnlockCode { get { return "1111"; } }
}

答案 3 :(得分:0)

如果初始化pin并将其转换为可为空的int,则只需要一个循环:

int? pin = null;
int enteredPin;
int realPin = 1111;
while(pin != realPin)
{
    if (pin.HasValue)
    {
        Console.Write("Wrong Password: ");
    }
    while(!int.TryParse(Console.ReadLine(), out enteredPin))
    {
        Console.Write("Please enter 4 numbers please: ");
    }
    pin = enteredPin;
}

最初pin!= realPin您的代码将进入您的循环,因为它没有值,您将不会输出错误消息。

答案 4 :(得分:-1)

也许你可以试试:

        int pin;
        int realPin = 1111;
        Console.Write("What's the pin: ");
        foreach (var item in Console.ReadLine())
        {
            if (!int.TryParse(item.ToString(), out pin))
            {
                Console.Write("Please enter a 4 numbers please: ");
            }
            if (pin.ToString().Length == 4)
            {
                Console.Write("Please enter a 4 numbers please: ");
            }
            else if (pin != realPin)
            {
                Console.Write("Wrong Password: ");

            }
        }