我制作了一个程序来检查用户引脚是否正确,但只检查引脚是否为整数。无论如何,通过仅使用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: ");
}
}
答案 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: ");
}
}