【问题标题】:How to Loop until a variable inputted by the user is an integer in VB.NET?如何循环直到用户输入的变量是VB.NET中的整数?
【发布时间】:2014-06-10 04:35:30
【问题描述】:

这是我目前的代码:

Module Module1

    Sub Main()
        Dim A, B, C, D As Integer
        Do
            Try
                System.Console.WriteLine("How high is the cube?")
                A = Int32.Parse(Console.ReadLine())
            Catch leg As System.FormatException
                System.Console.WriteLine(leg.Message)
            Finally
            End Try
        Loop Until A =
        System.Console.WriteLine("How wide is the cube?")
        B = Int32.Parse(Console.ReadLine())
        System.Console.WriteLine("How long is the cube?")
        C = Int32.Parse(Console.ReadLine())
        D = A * B * C
        Console.WriteLine(D)
        System.Console.ReadKey()
    End Sub

End Module

我希望第一个 try 块循环直到 A 是一个整数,以防用户输入字母而不是数字。有谁知道我该怎么做?

【问题讨论】:

  • 使用 Try...Catch 作为程序控制是一个可怕的想法。在那里放一个 if 或一段时间。与使用 while 循环或 if/then/else 进行测试的正确设计的代码块相比,抛出和处理异常需要更多的执行时间。
  • 这是我正在学习并提交给讲师的编程课程。我需要将 Try catch 循环作为作业的一部分。
  • 您没有正确使用 try/catch。 Try catch 不应该用于程序控制。它应该用于捕获和处理意外错误。您在此处捕获的错误是预期错误,应使用适当的编程结构进行处理;如果/同时/等。如果使用 Try/Catch 是分配的一部分,请正确使用它来捕获函数的错误。
  • 在此特定程序中用户输入不会导致太多错误。找到立方体的体积是他们让我做的程序之一。唯一可能发生的错误是用户输入了除整数以外的任何内容,还是我遗漏了什么?
  • 对于作业,您的教授似乎试图让您使用 try/catch 来控制程序流程,但是您应该知道,对于您未来的编程生活,使用 try/catch 作为程序控制是不好。不要在现实世界中这样做。

标签: vb.net loops input integer console-application


【解决方案1】:

我还有一个概念要补充。方法触发异常,让您处理不太可能的问题并防止应用程序崩溃。 readlin 和 writeline 可以抛出异常,如果你不捕捉它们并且它们发生了,你的程序就会崩溃。使用 try 块来完成它的意义:处理不太可能的崩溃以增加健壮性。要彻底完成工作,您应该研究异常并编写代码以防止崩溃。

【讨论】:

    【解决方案2】:

    这里有一个真实的例子来进一步解释为什么使用 Try/Catch 来控制程序流是不好的一个原因。至少在 .NET 中,抛出错误并在 catch 中处理它比使用适当的控制流结构正确处理错误需要更多的执行时间。

    我从一位同事那里接了一个项目,他正在使用一个函数来清理应该是数字的输入。他正在使用类似以下代码的代码来执行此操作。

    Public Shared Function SafeDouble(value As Object, Optional DefaultValue As Double = 0.0) As Double
        Dim CleanDouble As Double
    
        Try
            CleanDouble = CDbl(value) 'try to convert to a double
        Catch ex As Exception
            CleanDouble = DefaultValue 'if it fails use the default value
        End Try
    
        Return CleanDouble
    End Function
    

    这对于他最初用来处理一行数据的地方来说效果很好。当我开始使用它来处理 1000 行数据时,问题就出现了。当执行到导入的这一部分时,执行陷入了很长时间。

    使用一些计时器,我确定每个无法转换并引发异常的值需要 50 到 100 毫秒。

    我更改了代码以使用适当的控制结构,并且时间下降到每个无法转换的值的 2 到 5 毫秒。当前代码如下。我知道可能会出现一些不是数字的值。如果不是数字,我直接分配默认值。

    Public Shared Function SafeDouble(value As Object, Optional DefaultValue As Double = 0.0) As Double
            Dim CleanDouble As Double
    
            Try
                If IsNumeric(value) Then 'test to see if the data is numeric before converting it
                    CleanDouble = CDbl(value)
                Else
                    CleanDouble = DefaultValue 'if it isn't numeric, use default value
                End If
            Catch ex As Exception
                CleanDouble = DefaultValue 'if something unexpected happens, use default value
            End Try
    
            Return CleanDouble
        End Function
    

    如您所见,我已经处理了它未转换的预期错误,因为它不是数字。这应该解释了可能发生的大多数问题。我仍然保留 try/catch 以防发生其他意外错误。

    【讨论】:

      【解决方案3】:

      在 C# 中(转换为 VB 是读者的练习):

      public static Int32 GetInt32() {
      
          Int32 value;
          while( !Int32.TryParse( Console.ReadLine(), out value ) ) {
              Console.WriteLine("Please enter an integer");
          }
          Console.WriteLine("You entered {0}", value);
          return value;
      }
      

      【讨论】:

      • Posted 方法的返回类型为 Int32 但不返回。
      • @pinkfloydx33 哎呀!固定:)
      【解决方案4】:

      使用 TryParse 代替你的 try/catch 块和 do 循环。成功时返回True,并将int32值放入变量a中。

                  Dim a As Integer, tmp As String
      
                  Do
                      System.Console.WriteLine("How high is the cube?")
                      tmp = Console.ReadLine()
                  Loop While Int32.TryParse(tmp, a) = False
      

      循环之后,a 中存储的值将是一个整数。对其他每个值重复此操作。

      您也可以像 Dai 在他的 C# 示例中那样做,而不用费心存储到临时变量中:

              Dim a As Integer
      
              Do
                  System.Console.WriteLine("How high is the cube?")
              Loop While Int32.TryParse(Console.ReadLine(), a) = False
      

      如果您必须使用 Try/Catch 进行作业,您可以尝试此操作,但出于实际目的,我会按照上述方法进行操作。

              Dim a As Integer, valid As Boolean = True
              Do
                  Try
                      System.Console.WriteLine("How high is the cube?")
                      a = Int32.Parse(Console.ReadLine())
                  Catch ex As Exception
                      valid = False
                  End Try
              Loop While Not valid
      

      【讨论】:

      • 你不需要你的 try/catch 块。 TryParse 是为你做的。另外,请参阅原始帖子中的 KevenDenen 的 cmets。不要使用 try/catch 进行流量控制
      • 如果拥有和使用 try/catch 块不是任务的一部分,那么我可能会摆脱它们。有什么办法可以保留它们吗?
      • 这样做确实没有意义,但是如果您必须使用 try/catch,我已经添加了替代答案
      猜你喜欢
      • 2020-08-15
      • 2018-07-15
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      相关资源
      最近更新 更多