Проверка Visual Basic - PullRequest
       1

Проверка Visual Basic

0 голосов
/ 18 октября 2019

Я новичок в Visual Basic, и я попытался реализовать проверку ввода для ввода Mark в моем приложении, где ввод не может быть пустым или <0</strong> или > 100 или isnumeric (Mark) = False , иначе может появиться сообщение об ошибке. Однако я попытался оставить ввод пустым или ввести алфавитные значения, но вместо этого он вернул ошибку времени выполнения. Может ли кто-нибудь помочь мне в некоторых объяснениях, а также как преодолеть это? Извиняюсь, если это тупой вопрос.

Примечание. Тип данных для переменной "Mark" установлен как single. Спасибо за ваше время!

Sub InputMark()
     4: For I = 0 To 3
        Console.WriteLine("Please enter test marks for test " & I + 1)
        Mark(I) = Console.ReadLine

        While Mark(I) = Nothing Or Mark(I) < 0 Or Mark(I) > 100 Or IsNumeric(Mark(I)) = False
            Console.WriteLine("Please enter valid test marks.")
            GoTo 4
        End While
    Next
End Sub

Ответы [ 3 ]

2 голосов
/ 18 октября 2019

Пара вещей:

  1. Включить параметр строго на: https://github.com/dday9/vb.net-tutorial/blob/master/Section%201/Chapter%201.md
  2. Использование Single.TryParse для результата ReadLine.
  3. ABANDON GOTO '! В этом случае будет достаточно простого цикла Do.

Взгляните на этот пример:

Option Strict On
Option Explicit On

Imports System

Public Module Module1
    Public Sub Main()
        ' Declare an array of Single values
        Dim marks(3) As Single

        ' Loop from 0 to n (in this case 3)
        For counter As Integer = 0 To marks.Length - 1
            ' Declare a variable to check if the conversion was succesful
            Dim success As Boolean = False

            ' Start a Do/Until loop
            Do
                ' Propt the user to enter something
                Console.WriteLine("Please enter test marks for test " & counter + 1)

                ' Check if the conversion from ReadLine to a Single is valid
                success = Single.TryParse(Console.ReadLine(), marks(counter)) AndAlso marks(counter) >= 0 AndAlso marks(counter) <= 100

                ' If not then scold the user
                If (Not success) Then
                    Console.WriteLine("Please enter valid test marks.")
                End If
            Loop Until success
        Next

        ' Debug - just print out the values of marks
        For Each mark As Single In marks
            Console.WriteLine(mark)
        Next
    End Sub
End Module

Live Demo: https://dotnetfiddle.net/guoAzP

2 голосов
/ 18 октября 2019

Тип данных для переменной "Mark" задан как одиночный.

Одна из приятных вещей в строго типизированных платформах, таких как .Net, состоит в том, что большинство ваших правил проверки:1005 * уже применяется . Вы не сможете назначить нечисловое значение для Mark, а в качестве типа значения оно не может быть даже null (Nothing в VB.Net оценивается как 0 для типа Single.

Итак, вместо этого нам нужно выполнить резервное копирование и найти, где данные получены от пользователя, за до они назначаются на Mark переменная. Где-то у вас будет код типа Mark(I) = Console.Readline() или аналогичный. Вот где должно быть ваше тестирование. Проверьте значение string , полученное от пользователя до того, как присвоит значение Single. И когда вы дойдете до этого момента, лучший способ выполнить это тестирование - это функция Single.TryParse() . Затем вы можете проверить, что проанализированное значение Single находится в правильном диапазоне.


Хорошо, с более полным кодом мы можем начать давать вам реальные улучшения.

Одно из предложений - думать о возврате значения. Лучше, чтобы эта функция возвращала массив, а не общалась через глобальную переменную. Я упоминаю это здесь, потому что это также будет означать изменение способа вызова этой функции.

Это вне пути:

Function InputMarks() As Single()
     Dim result(3) As Single

     For I As Integer = 0 To 3
        Dim ErrorMsg As String = ""
        Do 
            Console.Write($"{ErrorMsg}Please enter test marks for test {I+1}: ")
            Dim input As String = Console.ReadLine()
            ErrorMsg = $"{vbCrLf}Please enter valid test marks.{vbCrLf}{vbCrLf}"
        While Not Single.TryParse(input, result(I)) OrElse result(I) < 0 OrElse result(I) > 100
     Next

    Return result
End Function

Нет GOTO требуется или требуется.

Если вы еще не видели их, $"strings" используют строковая интерполяция и оператор OrElse вместо Or предназначены для получения режима короткого замыкания. Современный VB.Net должен использовать OrElse и AndAlso вместо Or и And почти все время.

В этом случае использование OrElse означает, что мы уверены, что Single.TryParse() успешно завершено, и у нас будет действительное число до того, как попытается проверить диапазон. Если операция разбора не удалась, тесты диапазона даже не будут предприняты.

1 голос
/ 18 октября 2019

Я собираюсь разбить это на более мелкие функции.

Во-первых, здесь есть функция для обработки строки, которая возвращает либо число, если оно удовлетворяет вашим условиям, либо Single.NaN.

Private Function validateMarkOrNaN(input As String) As Single
    Return If(Single.TryParse(input, validateMarkOrNaN) AndAlso 0 <= validateMarkOrNaN AndAlso validateMarkOrNaN <= 100, validateMarkOrNaN, Single.NaN)
End Function

Вот вторая функция, которая вызывает первую, когда ей нужно обработать пользовательский ввод. Эта функция обрабатывает поток одного входа. Его можно вызывать любое количество раз, требуя, чтобы вы передавали только индекс, чтобы его можно было набирать в консоли.

Private Function getMarkInput(index As Integer) As Single
    Dim result As Single
    Do
        Console.WriteLine($"Please enter test marks for test {index + 1}")
        result = validateMarkOrNaN(Console.ReadLine())
        If Single.IsNaN(result) Then Console.WriteLine("Please enter valid test marks.")
    Loop While Single.IsNaN(result)
    Return result
End Function

Ваша основная программа определяет общий поток. Здесь вы можете объявить, сколько меток будет прочитано, и выполнить цикл по вашему массиву, получая каждый вход в каждый элемент.

Sub Main()
    Dim numberOfMarks = 4
    Dim Mark(numberOfMarks - 1) As Single
    For i = 0 To numberOfMarks - 1
        Mark(i) = getMarkInput(i)
    Next
End Sub

Как и в вашем коде, это будет выполняться бесконечно, пока пользователь этого не сделает. введите действительное число с плавающей точкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...