Mohit Tomar Ответов: 3

Не удалось найти причину исключения переполнения


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

///summary
            ///Write a program, which creates an array containing all Latin letters.
            ///The user inputs a word from the console and as result the program
            ///prints to the console the indices of the characters matching array
            static void Main()
            {
            char ch = 'A';
            char[] alph = new char[26];
            for (int row = 0; row < 26; row++)
            {
                alph[row] = ch;
                ch++;
            }
            for (int row = 0; row < 26; row++)
            {
                Console.Write(alph[row] + " ");
            }
            Console.WriteLine();
            Console.Write("Enter word: ");
            string word = Console.ReadLine();
            string wordUpper = word.ToUpper();
            int wrdIdx = 0;
            for (int i = 0; true; i++)
            {
                if (wordUpper[wrdIdx] == alph[i]) //If below if is removed then this gives as error. Same error of overflow
                {
                    Console.Write(i + " ");
                    wrdIdx++;
                    i = 0;
                    if (wordUpper[wrdIdx] == wordUpper.Length - 1) //This line is giving error if i remove it then the error shows above in the IF statement.
                        break;
                }
            }
            }



Это вывод и сообщение об ошибке, которое я получаю:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Enter word: Mohit
12 14 7 8 19
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.String.get_Chars(Int32 index)
   at Revision.Program.Main(String[] args) in C:\Users\mohit\source\Revision\Revision\Program.cs:line 632


Что я уже пробовал:

Попытался отладить код. Но так как я новичок, то не могу понять, что происходит в отладчике.

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

Прошу также извинить меня за мой английский.

Заранее спасибо.

3 Ответов

Рейтинг:
27

Richard Deeming

if (wordUpper[wrdIdx] == wordUpper.Length - 1)

wordUpper[wrdIdx] возвращает char представление символа по указанному индексу.

wordUpper.Length - 1 возвращает int - число на единицу меньше длины строки.

Для того чтобы сравнить их, char будет преобразован в его кодовую точку Юникода. (Поскольку вы работаете только с буквами без акцента, это то же самое, что и его ASCII[^] ценность.)

Учитывая входную строку в верхнем регистре "MOHIT", числовое значение wordUpper[wrdIdx] будет: 77, 79, 72, 73 и 84 Очевидно, что ни одно из этих значений не равно wordUpper.Length - 1, так что ваш цикл никогда не заканчивается. Однажды wrdIdx пройдя мимо конца вашей струны, вы получите IndexOutOfRangeException когда вы пытаетесь получить доступ к следующему символу.

Одним из простых исправлений было бы использование вложенного цикла:
foreach (char c in wordUpper)
{
    for (int i = 0; i < alph.Length; i++)
    {
        if (c == alph[i])
        {
            Console.Write(i + " ");
            break;
        }
    }
}


Mohit Tomar

О-О-О-О... наконец-то я понял, почему мой код не работал. Поэтому я сравнивал коды char со значениями int num, а система преобразовывала символы в представление num в соответствии с ASCII, и именно поэтому она не работала. Хммм... хорошо... Спасибо за вашу помощь .. Я действительно ценю это. И это работает сейчас... Прежде всего, я узнал что-то новое, и это бесценно. :-)

Рейтинг:
2

OriginalGriff

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.String.get_Chars(Int32 index)

Это не "исключение переполнения" - это "исключение индекса массива", которое отличается.
Вот что он говорит: i больше, чем 25, или wrdIdx превышает длину слова. Почему? потому что ваш цикл выходит только в том случае, если все совпадает и он достигает break заявление.
Мы не можем запустить ваш код в тех же условиях, что и вы, так что это будет зависеть от вас.
К счастью, у вас есть инструмент, который поможет вам выяснить, что происходит: отладчик.

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

Извините, но мы не можем сделать это за вас - пришло время вам освоить новый (и очень, очень полезный) навык: отладку!


Mohit Tomar

Есть ли какой-нибудь удобный для начинающих учебник по отладке, на который я могу сослаться?? На самом деле прошел всего один месяц с тех пор, как я начал работать с C#, так что мои знания очень и очень ограничены.

OriginalGriff

Грузы, и грузы:
https://www.google.co.uk/search-что?q=visual+studio+debugger&oq=visual+studio+debugger&aqs=chrome..69i57j0l5.6712j0j7&sourceid=chrome&ie=UTF-8
А вот и MS one:
https://tutorials.visualstudio.com/vs-get-started/debugging

Mohit Tomar

Однако мне было интересно, почему петли разбить, когда она достигает -----если (wordUpper[wrdIdx] == wordUpper.Длина - 1) ----- потому что в это время значение как wordUpper[wrdIdx], так и wordUpper.Длина - 1 становится одинаковой.

OriginalGriff

Да, но это вложено в другое "если", поэтому оба условия должны быть истинными. Таким образом, если первое условие не совпадает, то есть хорошая возможность просто работать дальше и дальше, пока вы не получите проблему индекса массива.
Полагаться на то, что ваши данные будут действительны каждый раз, - это опасный маршрут...

Mohit Tomar

Спасибо.. :-)

OriginalGriff

Всегда пожалуйста!

Рейтинг:
2

Maciej Los

Сообщение об ошибке: System.IndexOutOfRangeException: Index was outside the bounds of the array это corelated с массивом. Индекс массива начинается от нуля до числа элементов минус 1. таким образом, первый элемент в массиве имеет индекс 0, второй - 1, Третий - 2, ... десятый - 9 и т. д.

Посмотри на свой for петли для решения вашей проблемы.