vb.net如果不是整数,如何拒绝用户输入

vb.net如果不是整数,如何拒绝用户输入,vb.net,Vb.net,我正在开发一个接受用户输入的程序。我试图拒绝他们的输入,如果是十进制或字母。我该怎么做 Function GetHowLongToRun() As Integer Dim Years As Integer Dim valid As Boolean = False Console.WriteLine("Welcome to the Plant Growing Simulation") Console.WriteLine() Console.WriteLine

我正在开发一个接受用户输入的程序。我试图拒绝他们的输入,如果是十进制或字母。我该怎么做

Function GetHowLongToRun() As Integer
    Dim Years As Integer
    Dim valid As Boolean = False
    Console.WriteLine("Welcome to the Plant Growing Simulation")
    Console.WriteLine()
    Console.WriteLine("You can step through the simulation a year at a time")
    Console.WriteLine("or run the simulation for 0 to 5 years")
    Console.WriteLine("How many years do you want the simulation to run?")
    Do
        Console.Write("Enter a number between 0 and 5, or -1 for stepping mode: ")
        Years = Console.ReadLine()
        Try
            If Years > -2 And Years < 6 Then
                valid = True
            Else
                Console.WriteLine("Invalid input. Enter a whole number between 0 and 5, or -1 for stepping mode: ", Years)
            End If
        Catch ex As Exception
            Console.WriteLine("Invalid input. Enter a whole number between 0 and 5, or -1 for stepping mode: ")
            GetHowLongToRun()
        End Try
    Loop Until valid
    Return Years
End Function
函数GetHowLongToRun()为整数 作为整数的模糊年份 Dim有效值为布尔值=False Console.WriteLine(“欢迎来到植物生长模拟”) Console.WriteLine() WriteLine(“您可以一年一次地逐步完成模拟”) Console.WriteLine(“或运行模拟0到5年”) WriteLine(“您希望模拟运行多少年?”) 做 写入(“输入一个介于0和5之间的数字,或-1表示步进模式:”) 年份=Console.ReadLine() 尝试 如果年份>-2且年份<6,则 有效=真 其他的 Console.WriteLine(“输入无效。请输入介于0和5之间的整数,或-1表示步进模式:”,年) 如果结束 特例 Console.WriteLine(“输入无效。请输入介于0和5之间的整数,或-1表示步进模式:”) GetHowLongToRun() 结束尝试 循环直到有效 回归年 端函数
这里有多个问题:

  • Console.ReadLine()
    始终返回一个
    字符串
    ,但它会立即分配给一个
    整数
    值。这种编译完全说明了一种非常糟糕的做法,即关闭了
    选项Strict
    。最好使用
    Integer.Parse()/TryParse()
    Convert.ToInt32()
    CInt()
    中的任意一种
  • 代码以两种不同的方式处理故障:使用循环和重新调用函数。后一个选项可能会导致一个永无止境的递归循环,这最终会创建一个不可调度的StackOverflowException情况
  • 要修复它,您可以删除异常处理程序中额外的
    GetHowLongToRun()
    调用。循环将确保代码再次尝试。但我会更进一步,以更通用的方式将输入隔离到它自己的函数:

    Public Function ReadInteger(ByVal Prompt As String, ByVal InvalidPrompt As String, ByVal Retries As Integer, Optional ByVal MinValue As Integer = 0, Optional ByVal MaxValue As Integer = Integer.MaxValue)
        Dim attemptCount As Integer = 0
        While attemptCount < Retries
            Console.Write(Prompt)
            Dim input As As String = Console.ReadLine()
    
            Dim result As Integer
            If Integer.TryParse(input, result) Then
                 If result >= MinValue AndAlso result <= MaxValue Then
                     return result
                 End If
            End If
    
            Console.WriteLine(InvalidPrompt)
            attemptCount += 1
        End While    
    
        Throw New InvalidOperationException()
    End Function
    

    您可以使用正则表达式检查输入是否符合您的要求。这很方便,因为您可以在一条语句中检查多个条件

    您首先需要包括正则表达式库:

    Imports System.Text.RegularExpressions
    
    然后创建一个regex对象,将所需的模式指定为构造函数参数:

    Dim regex As Regex = New Regex("\d+")
    
    此正则表达式模式\d+将标识具有1个或多个连续数字的字符串。正则表达式功能强大,如果愿意,可以修改模式使其更加具体。网上有很多文档

    使用Regex对象的“Match”方法,您可以测试字符串,看看它们是否匹配指定的模式。这将返回“Match”类型的对象:

    Dim match as Match = regex.Match(Years)
    
    最后,使用match对象的“Success”属性检查匹配是否成功

    If match.Success Then
        valid = True
    End If
    
    或者,您可以将输入字符串解析为整数。如果解析失败,您就知道它不是有效的输入:

    If Integer.TryParse(Years) Then
        valid = True
    End If
    

    评论和解释一致

    Dim Years As String = Console.ReadLine()
    Dim HowLongToRun As Integer = GetHowLongToRun(Years)
    
    Function GetHowLongToRun(input As String) As Integer
            Dim valid As Boolean = False
            Dim ValidYears As Integer
            Do
                '.TryParse not only tests for a valid number and returns True or False but
                'if it finds a valid number it will assign it to the second parameter
                'The AndAlso portions of the If will not be evaluated unless the first portion is True.
                'This is called short-circuiting.
                If Int32.TryParse(input, ValidYears) AndAlso ValidYears < 6 AndAlso ValidYears > -2 Then
                    valid = True
                Else
                    'You are misusing the (String, Object) overload of Console.WriteLine
                    'This is meant as a sort of variation on String.Format where the second parameter
                    'is substituted for a place holder in the string like {0}
                    'Since there is no placeholder, I deleted the , Years
                    Console.WriteLine("Invalid input. Enter a whole number between 0 and 5, or -1 for stepping mode: ")
                    input = Console.ReadLine
                End If
            Loop Until valid
            Return ValidYears
    End Function
    
    Dim Years As String=Console.ReadLine()
    Dim HowLongToRun作为整数=GetHowLongToRun(年)
    函数GetHowLongToRun(作为字符串输入)为整数
    Dim有效值为布尔值=False
    Dim validears作为整数
    做
    “.TryParse不仅测试有效数字并返回True或False,而且
    '如果它找到一个有效的数字,它将把它分配给第二个参数
    “除非第一部分为真,否则不会对If的AndAlso部分进行评估。
    这叫做短路。
    如果Int32.TryParse(输入,validears)和also validears<6和also validears>-2,则
    有效=真
    其他的
    '您误用了Console.WriteLine的(字符串、对象)重载
    '这是对String.Format的一种变体,其中第二个参数
    '替换字符串中的占位符,如{0}
    '由于没有占位符,我删除了年
    Console.WriteLine(“输入无效。请输入介于0和5之间的整数,或-1表示步进模式:”)
    input=Console.ReadLine
    如果结束
    循环直到有效
    返回有效期
    端函数
    
    Console.ReadLine()返回字符串,而不是整数。通过使用Integer.TryParse()进行转换来改进代码。当您在源文件顶部启用Option Strict时,编译器可以帮助您找到类似这样的错误。
    Dim Years As String = Console.ReadLine()
    Dim HowLongToRun As Integer = GetHowLongToRun(Years)
    
    Function GetHowLongToRun(input As String) As Integer
            Dim valid As Boolean = False
            Dim ValidYears As Integer
            Do
                '.TryParse not only tests for a valid number and returns True or False but
                'if it finds a valid number it will assign it to the second parameter
                'The AndAlso portions of the If will not be evaluated unless the first portion is True.
                'This is called short-circuiting.
                If Int32.TryParse(input, ValidYears) AndAlso ValidYears < 6 AndAlso ValidYears > -2 Then
                    valid = True
                Else
                    'You are misusing the (String, Object) overload of Console.WriteLine
                    'This is meant as a sort of variation on String.Format where the second parameter
                    'is substituted for a place holder in the string like {0}
                    'Since there is no placeholder, I deleted the , Years
                    Console.WriteLine("Invalid input. Enter a whole number between 0 and 5, or -1 for stepping mode: ")
                    input = Console.ReadLine
                End If
            Loop Until valid
            Return ValidYears
    End Function