От новичка до гуру: Курсы программирования на CyberDuff

Индекс находился вне границ массива. ВБ

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

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 становится отрицательным, и программа вылетает. Почему условие не работает должным образом?

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

30.06.2018

  • Отследите, откуда исходит -1. Я думаю, это должно быть 0 или 1. Это потому, что вычитание приводит к этому? Это возвращаемое значение по умолчанию для нигде не найдено? 30.06.2018
  • Это полезная информация, даже если это гипотеза, которую нужно редактировать в вопросе. 30.06.2018
  • Не было бы проще, если бы пользователь дважды щелкнул слово и использовал свойства .SelectionChanged, .SelectionStart, .SelectionLength и .SelectedText? 30.06.2018

Ответы:


1

Если вы не хотите, чтобы пользователь дважды щелкал, как предложил Дэвид Уилсон (с чем я также согласен), тогда это даст желаемый результат. При этом учитывается, является ли предыдущий символ переводом строки или началом текста, или следующий символ также является переводом строки или концом текста. Вы можете добавить к 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. Итак, если ваш индекс вы pass through — это начало слова «over», оно попадет в Throw New IndexOutOfRangeException("Index out of range!"), так как индекс будет равен 26, что, очевидно, больше 8.

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

01.07.2018
Новые материалы

Основы Spring: Bean-компоненты, контейнер и внедрение зависимостей
Как лего может помочь нашему пониманию Когда мы начинаем использовать Spring, нам бросают много терминов, и может быть трудно понять, что они все означают. Итак, мы разберем основы и будем..

Отслеживание состояния с течением времени с дифференцированием снимков
Время от времени что-то происходит и революционизирует часть моего рабочего процесса разработки. Что-то более забавное вместо типичного утомительного и утомительного процесса разработки. В..

Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..

Игра в прятки с данными
Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

«Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..

Раскройте свой потенциал в области разработки мобильных приложений: Абсолютная бесплатная серия
Глава 6: Работа в сети и выборка данных Глава 1: Введение в React Native Глава 2: Основы React Native Глава 3: Создание пользовательского интерфейса с помощью React Native Глава 4:..

Все о кейсах: Camel, Snake, Kebab & Pascal
В программировании вы сталкивались с ними при именовании переменной, класса или функции. Поддержание согласованности типов и стилей случаев делает ваш код более читабельным и облегчает совместную..