Индекс находился вне границ массива. VB - PullRequest
0 голосов
/ 30 июня 2018

Я пытался создать программу, которая найдет слово, на которое щелкнул пользователь, в многострочном текстовом поле. Эта процедура основана на индексе с позиции щелчка. Код, который я реализовал:

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

Проблема в том, что когда программа достигает строки:

previousCh = TextBox1.Text.Chars(previousIndex)

выходит с:

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

Пока генерируется исключение, при наведении курсора на переменную previousIndex Visual Studio показывает мне его значение: -1.

Я думаю, что условие previousCh = " " никогда не выполняется, поэтому программа никогда не выходит из цикла while, который продолжает искать предыдущий символ. В какой-то момент int previousIndex становится отрицательным, и программа вылетает. Почему условие не работает должным образом?

В чем проблема? Спасибо.

1 Ответ

0 голосов
/ 01 июля 2018

Если вы не хотите, чтобы пользователь дважды щелкнул, как предложил Дэвид Уилсон (с чем я бы тоже согласился), тогда вы получите желаемый результат. Он учитывает, является ли предыдущий символ переводом строки или началом текста, либо следующий символ также переводом строки или концом текста. Вы можете добавить к If, чтобы найти «,» или «.» если нужно.

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

Также в вашей функции GetWordByIndex вы разбиваете входную строку на массив

Dim words = input.Split(" ")

тогда вы говорите

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

но когда вы вызываете .length для массива, он возвращает количество строк (или что-то еще в массиве). Например, если ввод был "Большая коричневая лиса перепрыгнула через ленивую собаку", words.length - 1 вернет 8. Таким образом, если ваш индекс, через который вы проходите, является началом слова «over», оно попадет в Throw New IndexOutOfRangeException("Index out of range!"), так как индекс будет 26, что, очевидно, больше 8.

Код, который я предоставил, не использует функцию для поиска слова, но я все равно хотел бы упомянуть об этом.

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