【问题标题】:Validating multiple user input in console application在控制台应用程序中验证多个用户输入
【发布时间】:2015-04-22 02:39:45
【问题描述】:

我是 C# 的新手,想知道如何验证用户输入以满足以下要求:

  • 必须是十进制类型。如果不是,它应该要求用户输入一个十进制值。 (我相信我已经在下面的代码中介绍过)
  • 还必须在特定范围内 (1 - 1,000,000)。如果不是,则应要求用户输入正确范围内的数字

考虑到我将有多个用户输入以相同的方式进行验证,这样做最有效的方法是什么。

decimal balance;
Console.Write("Starting Balance: $");
while (!decimal.TryParse(Console.ReadLine(), out balance))
{
    Console.Write("Please enter a valid decimal value: $");
}

以下编辑

这个怎么样?

decimal balance;
Console.Write("Starting Balance: $");
while(true)
{
    if (!decimal.TryParse(Console.ReadLine(), out balance))                
        Console.Write("Please enter a valid decimal value: $");
    else if (balance < 1 || balance > 100)
        Console.Write("Please enter an amount between 1 and 100: ");
    else
        break;                
}
Console.WriteLine("Balance entered is: " + balance.ToString("n"));

return val; 行给了我一个错误,所以我忽略了它,但上面的方法似乎有效?

【问题讨论】:

  • 您使用的是哪种技术?表格? ASP.NET? ASP.NET MVC?如果可能,您可以尝试数据注释。
  • 不确定您所说的 WinForms 是什么意思? ASP.NET?
  • 我只是接受来自控制台的输入。
  • 您正在创建一个应用程序。代码只是为应用程序提供逻辑。什么样的应用程序会使用你的代码?或者如果您使用的是 Visual Studio,您的项目类型是什么?
  • 高效是什么意思?您可以修改您的 while 以满足您的范围要求:while (!decimal.TryParse(Console.ReadLine(), out balance) || balance &lt; 1 || balance &gt; 1000000)

标签: c# validation loops input console-application


【解决方案1】:

我会尝试类似:

decimal GetUserInput(string inputQuery, decimal min, decimal max)
{
  Console.Write(inputQuery);
  decimal val;
  while(true)
  {
    if(!decimal.TryParse(Console.ReadLine(), out val))
      Console.Write("Please enter a valid decimal value: $");
    else if(val < min || val > max)
      Console.Write("Please enter an amount between " + min + " and " + max + ": $");
    else // the value is a decimal AND it's correct
      break;
  } 
  return val;
}

然后像这样使用它:

var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);
//...

如果您的最小值和最大值是固定的,那么您不能将它们作为参数传递并使用固定检查。如果需要,您还可以避免传入查询 : $,但我将把它留给您

更新

return val 行给你一个错误的原因是因为你将它内联(可能在void 返回函数中)。我所做的是创建一个函数,因为您指定它需要可重用。

所以在你的程序中,你需要创建一个单独的函数......你的程序看起来像这样:

class Program
{
    // We're declaring this function static so you can use it without an instance of the class
    // This is a function, so it can be called multiple times, with different arguments
    static decimal GetUserInput(string inputQuery, decimal min, decimal max)
    {
      // Write the argument "inputQuery" to console
      Console.Write(inputQuery);
      decimal val;

      // Loop indefinitely
      while(true)
      {
        // Read from console into a decimal "val"
        if(!decimal.TryParse(Console.ReadLine(), out val))
          // It was not a correct decimal, so write the prompt
          Console.Write("Please enter a valid decimal value: $");
        // It was a correct decimal
        else if(val < min || val > max)
          // But not in range, so write a different prompt
          Console.Write("Please enter an amount between " + min + " and " + max + ": $");
        // It was a decimal and within range
        else
          // so we break the infinite loop and exit after the "}"
          break;

        // If we have got to this point (we didn't hit the "break"),
        // it was either not a decimal or it wasn't within range, 
        // so it'll loop again and ask for a value from console again.
        // The prompt was already written above (in the "ifs")

      } 
      // We got out of the while(true){} loop, so it means we hit "break"
      // above, and that means "val" contains a correct value (decimal and
      // within range), so we return it to the caller
      return val;
    }

    static void Main()
    {
      // Your original code went here, but see how my function is *outside* function Main()

      // You use my function (GetUserInput) here:
      var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
      var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);

      // Then with the returned values (stored in "startingBalance"
      // and "endBalance"), you can do what you want:
      Console.WriteLine("Starting balance was: " + startingBalance.ToString("n"));
    }
}

我已经对整个程序进行了修改,以便您可以在线测试并进行更改:https://dotnetfiddle.net/HiwwIP

【讨论】:

  • 我做了一个允许重用的函数,但是如果你只需要内联代码,那就可以了
  • @Bobby 作为 Stack Overflow 中的一般规则,不要编辑其他人的答案来添加自己的 cmets,只是为了修复错误或格式等。我已经更新了我的答案,所以你可以看看如何我的代码打算被使用,为什么return 语句给出了错误。我添加了 cmets,这样您就可以看到发生了什么,并为您测试小提琴
【解决方案2】:

如果我是你,我会这样做:

        bool isInvalid, isOutOfRange;
        decimal balance = 0;
        isOutOfRange = true;
        do
        {
            string input = Console.ReadLine();
            isInvalid = !Decimal.TryParse(input, out balance);
            if (!isInvalid)
            {
                // use balance<=1 if 1 should not be included
                // use balance>=1000000 if 1000000 should not be included
                isOutOfRange = (balance < 1 || balance > 1000000);
            }
            if (isInvalid)
            {
                Console.WriteLine("Please enter a valid decimal value: $");
            }
            else if (isOutOfRange)
            {
                Console.WriteLine("Please enter value between 1 and 1000000: $");
            }

        } while (isInvalid || isOutOfRange);
        Console.WriteLine("{0}, That is a valid value!", balance.ToString());
        Console.ReadKey();

当然,您可以通过消除bool 定义并直接调用函数来实现快捷方式;但为了清楚起见,我写得很详细,因为你表示你是“相当新的”。

【讨论】:

  • 选民能否至少详细说明一下投反对票的原因,以便我可以解决它?
  • 我对此投了反对票:(balance &lt;= 1 &amp;&amp; balance &gt; 1000000); 这显然总是错误的。但是,您现在已经将其编辑了。但这仍然不会验证我相信 OP 想要的 1 的输入。 also has to be within a specific range (1 - 1,000,000)
  • 是的,我一发布就看到了。仍然感谢您指出。我会尽快纠正
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
  • 2015-08-23
相关资源
最近更新 更多