如何检查一个变量是否等于另一个,而使用try解析

本文关键字:另一个 try 解析 变量 检查 何检查 一个 是否 | 更新日期: 2023-09-27 18:17:32

我编写了一个程序来检查用户的pin是否正确,但它只会检查pin是否为整数。有没有办法通过只使用一个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: ");
    }
}

如何检查一个变量是否等于另一个,而使用try解析

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

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;
}

代码在性能方面并不更有效,但它是以更DRY的方式考虑的

我建议分隔语法错误(例如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

实际上根本不需要将值转换为整数,只比较字符串更容易,因此您不妨退回到执行单个测试。这也意味着像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"; } }
}

如果初始化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,你的代码将进入你的循环,因为它没有一个值,所以你不会输出错误消息

也许你可以试试:

        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: ");
            }
        }