Bubblebeard Bubblebeard - 2 months ago 5x
Vb.net Question

Input validation in textbox using specific letters

I'm trying to limit the letters you can use in a 5 text boxes to "D, H, C and S"

The code I have is:

suit(0) = txtSuit1.Text
suit(1) = txtSuit2.Text
suit(2) = txtSuit3.Text
suit(3) = txtSuit4.Text
suit(4) = txtSuit5.Text

For i As Integer = 0 To 4
If suit(i) <> "D" And suit(i) <> "H" And suit(i) <> "C" And suit(i) <> "S" And suit(i) = "" Then
MessageBox.Show("Choose a suit using D for Diamonds, H for Hearts, C for Clubs or S for Spades")
End If

Even if I put in random letters, the message box will not show up. And using Or instead of And makes the message box pop up every time.

Also having an issue with throwing a message box in this code if the box if left blank:

cards(0) = CInt(txtCard1.Text)
cards(1) = CInt(txtCard2.Text)
cards(2) = CInt(txtCard3.Text)
cards(3) = CInt(txtCard4.Text)
cards(4) = CInt(txtCard5.Text)

For i As Integer = 0 To 4
If cards(i) > 13 Or cards(i) < 1 Or Not IsNumeric(cards(i)) Or cards(i) = "" Then
MessageBox.Show("Enter a number between 1-13")
End If

Every time there is a blank box, I get an error saying string "" to type 'Integer' is not valid.
How do I go about throwing a message box when the textbox is left blank?


It is usually better to provide a way that users cannot give you bad input rather than write code to scold them when they do not. For that, use a ComboBox for suits and a NumericUpDown for the card ranks.

Otherwise, simple code to validate what you have collected:

' suit is your string array of suit letters
Dim suitCodes = {"H", "C", "D", "S"}

Dim bValid As Boolean = True
For Each s As String In suit
    If suitCodes.Contains(s) = False Then
        bValid = False
    End If
If bValid = False Then
    MessageBox.Show("Please enter only 'H, C, S, D' for suits")
End If

And never put a MessageBox inside a loop - they only need to be told once, told once, told once.

Much the same thing can initially be done for numerics, but you have to allow that they enter text rather than numerals. For that use TryParse rather than CINT:

' cards is a bad var name
Dim ranks(4) As Int32

If Integer.TryParse(TextBox1.Text, ranks(0)) Then
    If ranks(0) < 1 OrElse ranks(0) > 13 Then bValid = False
    bValid = False
End If

But you have a bigger problem looming. In most cases, Aces are high but you appear to be storing them as 1 (Lo). You don't want a pair of threes to appear to beat a pair of Aces, so you should convert them:

Dim temp As Int32
If Integer.TryParse(TextBox1.Text, temp) Then
    If temp > 0 AndAlso temp < 14 Then
        If temp = 1 Then
            ' store Ace as Hi:
            ranks(0) = 14
            ranks(0) = temp
        End If
    End If
    bValid = False
End If

Alternatively, have them enter values from 2-14.