【问题标题】:How to prevent certain forms of input when writing methods?编写方法时如何防止某些形式的输入?
【发布时间】:2012-06-27 13:14:00
【问题描述】:

我仍然是高级编程语言的初学者,所以我不知道这是否是一个简单的解决方案,但无论如何我很乐意学习。我在 C# 中编写了一个小警报程序,让用户输入警报需要在多少秒内响起。它工作得很好,但用户需要提供的输入必须是一个数字。当用户输入任何形式的文本时,程序就会崩溃。现在,如何防止用户输入文本、调用函数或在用户输入时执行其他操作,而不是让程序崩溃?

这是我现在的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    class Alarm
    {
        public static void play()
        {
            int sec;
            sec = Convert.ToInt16(Console.ReadLine());

            for (int i = 0; i < seconds; ++i)
            {
                System.Threading.Thread.Sleep(1000);
            }

            for (int i = 0; i < 10; i++)
            {
                Console.Beep();
            }
        }
    }
}

【问题讨论】:

  • 好吧,在我的脑海中,你可以在转换周围使用try catch 并处理你喜欢的异常,例如要求他们重新输入一个值。
  • 另外,intInt32 而不是 Int16shortInt16 的别名
  • @JustinPihony 我什至不知道这一点。我接受了过去所有对我有帮助的答案。谢谢你的提示。 :)

标签: c# for-loop console


【解决方案1】:

您应该在转换前完成检查:

int sec;

if (int.TryParse(Console.ReadLine(), out sec)
{
  // this is valid continue
}
else
{
  // show error highlighting that entry must be a number
}

int.TryParse 将返回一个布尔值,突出显示输入是否可解析为 int。如果成功,它还会将您的 sec 变量设置为该值。

【讨论】:

  • 成功了,非常感谢!我只需要把它全部放在一个while循环中并创建一个布尔值来评估函数是否可以完成,就是这样。 :D
【解决方案2】:

您可以无限循环,直到用户输入一个数字:

int number = 0;
while(!Int32.TryParse(Console.ReadLine(), out number))
{
    Console.WriteLine("Please input a number.");
}

Int32.TryParse 如果转换失败则返回false,而不是抛出异常,如果成功则在第二个out 参数中返回结果。

【讨论】:

    【解决方案3】:

    这里已经有人回答了。 我喜欢把它写成extension method,这样我就可以在很多地方调用它。

    public static bool IsNumeric(this string theValue)
    {
      long retNum;
      return long.TryParse(theValue, System.Globalization.NumberStyles.Integer, 
                System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
    }
    

    那我就这样称呼它

    if(Console.ReadLine().IsNumeric())
    {
        //The value is numeric. You can use it    
    }
    

    【讨论】:

      【解决方案4】:

      你应该使用 try parse 方法。

      类似这样的:

        int number;
        bool result = Int32.TryParse(Console.ReadLine(), out number);
      

      如果结果为真,那么它已经成功解析它,这意味着它是一个整数。如果不是,它就失败了,这意味着它不是一个整数。

      然后您可以使用 number 作为解析为 int32 的值。

      【讨论】:

        【解决方案5】:

        替换

        sec = Convert.ToInt16(Console.ReadLine());
        

        try {
            sec = Convert.ToInt16(Console.ReadLine());
        }
        
        catch(Exception e ){
            Console.Writeline(" Enter numbers only");
        }
        

        【讨论】:

        • NO!,TryParse 的存在是有原因的,不要使用异常来正常控制流量。
        • @Scott:是对的。抛出异常更昂贵。尽可能避免它
        • 我不确定成本,但它消除了额外的 if 语句
        • @madhairsilence ,它的成本要高出几个数量级,运行 this simple program 并报告结果。
        • @madhairsilence 对我来说,使用TryParse 只运行一个循环的每个样式就可以让我提高 465,340%。因此,请想一想,当您在解析具有 100K 行的数据库中的记录时使用异常会发生什么。
        【解决方案6】:

        您尝试执行的操作通常称为Input Validation。在您的情况下,您需要在解析之前检查他们是否输入了一个数字。 Int16 有一个TryParse 函数可以帮助你。

        【讨论】:

          【解决方案7】:

          添加一个单独的函数,该函数使用 try 语句来捕获当您尝试将无效字符串转换为整数时产生的错误。

          int readInput()
          {
              int sec;
              while(true)
              {
                  try
                  {
                      sec = Convert.ToInt16(Console.ReadLine());
                      return sec;
                  }
                  catch(Exception e) 
                              { 
                                      Console.WriteLine("Enter an integer!");
                              }
              }
              return 0;
          }
          

          【讨论】:

          • 你不想这样做...形成控制流一部分的异常处理类似于在整个代码中使用非本地 goto 语句。
          【解决方案8】:

          如果您想做一些比显示错误消息并要求用户重新输入数据更优雅的事情,您可以尝试处理每个击键,就像 Console.Readkey() 发生的那样,如果会导致字符串不正确,则拒绝它们不是数字。

          几年前我在 TurboPascal 中做过类似的事情。

          这是从内存中编写的伪代码,但应该能让您走上正确的道路。如果您需要获取浮点值以及整数,或者负数和正数,则需要添加更多逻辑来处理这些情况。

          string enteredText = "";
          char key;
          bool done = false;
          while (!done) 
          {
             key = Console.ReadKey();
             if (key is number)
                 enteredText += key;
             else if (key is backspace)
             {
                 //remove the last char from enteredText.  Handle case where enteredText has length 0
                 Console.Write(backspace); 
             }
             else if ((key is enter) && (enteredText.Length > 0))
                 done = true;
             else
             {
                 // invalid char.
                 //MSDN says the char is echoed to the console so remove it
                 Console.Write(backspace);
                 //Beep at the user?
             }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-04-15
            • 2013-06-09
            • 1970-01-01
            • 2022-07-08
            • 1970-01-01
            • 2019-01-15
            • 1970-01-01
            • 2017-05-03
            • 1970-01-01
            相关资源
            最近更新 更多