Nick
Nick

Reputation: 241

Index was outside the bounds of the array. VB

I have been trying to create a program that will find the word the user has clicked on, in a multiline textbox. This procedure is based on the index from the position of the click. The code I implemented:

Public Class Form1

Private Sub TextBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles TextBox1.MouseDown
    If e.Clicks = 1 And e.Button = MouseButtons.Left Then
        'Try

        Dim indexClicked As Integer = TextBox1.GetCharIndexFromPosition(New Point(e.X, e.Y))

        Dim ch As Char = TextBox1.Text.Chars(indexClicked)
        Dim indexOfWord As Int32

        If Not ch = " " Then
            Dim wordFound As Boolean
            Dim previousCh As Char
            Dim previousIndex As Integer = indexClicked

            While Not wordFound
                previousIndex = previousIndex - 1
                previousCh = TextBox1.Text.Chars(previousIndex)
                If previousCh = " " Then
                    indexOfWord = previousIndex + 1
                    wordFound = True
                End If
            End While
        Else
            indexOfWord = indexClicked + 1
            End If
            Label1.Text = indexClicked & ", " & indexOfWord
            Label2.Text = GetWordByIndex(TextBox1.Text, indexOfWord)

        '  Catch ex As Exception
        '  Label2.Text = ex.Message
        ' End Try

    End If
End Sub

Public Shared Function GetWordByIndex(input As String, index As Integer) As String
    Try
        Dim words = input.Split(" ")
        If (index < 0) OrElse (index > words.Length - 1) Then
            Throw New IndexOutOfRangeException("Index out of range!")
        End If
        Return words(index)
    Catch ex As Exception
        'handle the exception your way
        Return String.Empty
    End Try
End Function
End Class

The problem is that whenever the program reaches the line:

previousCh = TextBox1.Text.Chars(previousIndex)

it exits with :

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in WindowsApplication1.exe
Additional information: Index was outside the bounds of the array.

While the exception is thrown, by hovering over the previousIndex variable visual studio shows me its value: -1.

I think that previousCh = " " condition never gets true, so the program never exits the while loop, which keeps looking for the previous character. At some point int previousIndex gets negative and the program crashes. Why does not the condtion work properly?

What is the problem? Thank you.

Upvotes: 0

Views: 564

Answers (1)

Pete
Pete

Reputation: 469

If you do not want to have the user double click like David Wilson suggested (which i would also agree with) then this will get the result you want. It takes into account if the previous character is a line feed or the start of the text, or the next character is a line feed or end of the text as well. You can add to the If to find "," or "." if needed.

Private Sub TextBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles TextBox1.MouseDown
    If e.Clicks = 1 And e.Button = MouseButtons.Left Then

        Dim startIndex As Integer = TextBox1.SelectionStart
        Dim wordStartFound, wordEndFound As Boolean
        Dim nextIndex, indexOfStartOfWord, indexOfEndOfWord, lengthOfWord As Integer

        If Not startIndex = 0 Then
            While Not wordStartFound
                startIndex = startIndex - 1
                If TextBox1.Text.Chars(startIndex) = " " Then
                    indexOfStartOfWord = startIndex + 1
                    wordStartFound = True
                ElseIf startIndex = 0 Then
                    indexOfStartOfWord = startIndex
                    wordStartFound = True
                ElseIf TextBox1.Text.Chars(startIndex) = Chr(10) Then 'Line Feed' 
                    indexOfStartOfWord = startIndex + 1
                    wordStartFound = True
                End If
            End While
        Else
            indexOfStartOfWord = startIndex
        End If

        nextIndex = startIndex

        While Not wordEndFound
            nextIndex = nextIndex + 1
            If TextBox1.Text.Chars(nextIndex) = " " Then
                indexOfEndOfWord = nextIndex
                wordEndFound = True
            ElseIf nextIndex = TextBox1.TextLength - 1 Then
                indexOfEndOfWord = TextBox1.TextLength
                wordEndFound = True
            ElseIf TextBox1.Text.Chars(nextIndex) = Chr(10) Then 'Line Feed' 
                indexOfEndOfWord = nextIndex
                wordEndFound = True
            End If
        End While

        lengthOfWord = indexOfEndOfWord - indexOfStartOfWord

        Label2.Text = TextBox1.Text.Substring(indexOfStartOfWord, lengthOfWord)

    End If
End Sub

Also in your function GetWordByIndex you split the input string into an array

Dim words = input.Split(" ")

then you say

If (index < 0) OrElse (index > words.Length - 1) Then Throw New IndexOutOfRangeException("Index out of range!") End If

but when you call .length on an array it returns the number of strings (or whatever is in the array) For example if the input was "The big brown fox jumped over the lazy dog", words.length - 1 will return 8. So if your index you pass through is the start of the word "over" it would fall into the Throw New IndexOutOfRangeException("Index out of range!") as the index would be 26 which is obviously greater than 8.

The code i have provided doesn't use the function to find the word but i thought i would mention that anyway.

Upvotes: 1

Related Questions