Member 13414754 Ответов: 4

Проблема с использованием подстроки - C#


У меня была небольшая проблема в C# с этим кодом:
string msg = words[cp].Substring(words[cp].IndexOf('=') + 2, words[cp].Length - 1);

Мне действительно нужно это исправить, потому что я пытаюсь создать язык программирования.

Вот исключение:
System.ArgumentOutOfRangeException occurred
  HResult=0x80131502
  Message=Index and length must refer to a location within the string.
Parameter name: length
  Source=mscorlib
  StackTrace:
   at System.String.Substring(Int32 startIndex, Int32 length)
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\*\source\repos\WindowsFormsApp1\ConsoleApp1\Program.cs:line 30


Вот мой код:
Lexer lex = new Lexer();

            string code = "def string s = hello world\nread key";
            int cp = 0;
            int ts = 0;
            lex.AddKeyword("def");
            lex.AddKeyword("string");
            lex.AddKeyword("read");
            lex.AddKeyword("key");
            string[] words = code.Split('\n');
            string[] identifers = new string[] { };
            if (words[cp].Substring(0, 3) == "def")
            {
                if (words[cp].Substring(4, 6) == "string")
                {
                    string msg = words[cp].Substring(words[cp].IndexOf('=') + 2, words[cp].Length - 1);
                    if (!words[cp].Contains('=') || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(".") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("+") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("=") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("-") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("(") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(")") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("*") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("&") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("^") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("%") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("$") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("#") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("@") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("!") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("~") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("`") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("1") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("2") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("3") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("4") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("5") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("6") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("7") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("8") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("9") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).StartsWith("0") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(";") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(":") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("\\") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("/") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("\"") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("'") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(".") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains(",") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("{") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("}") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("[") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("]") || words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4).Contains("|"))
                    {
                        Console.WriteLine("Syntax error: \nat: \n  " + cp + "\n-------------Press any key to continue-------------");
                        Console.ReadKey();
                    }
                    Console.WriteLine(msg);
                    identifers[cp] = words[cp].Substring(12, msg.Length - 1 - msg.Length - 1 - 4);
                    cp++;
                }
                else if (words[cp].StartsWith("read "))
                {
                    if (words[cp].Substring(6) == "key")
                    {
                        Console.WriteLine("-------------Press any key to continue-------------");
                        Console.ReadKey();
                    }
                }
            }


ЗАПИСКА:
Lexer-это пользовательский класс, созданный только для этой цели, в нем просто есть какой-то простой список<string> и методы для добавления к ним.

Я использую Visual Studio 2017 .NET Framework 4.6 (этот фреймворк поставляется вместе с пакетом)

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

Я перепробовал все, что смог найти, но ничего не работает.

4 Ответов

Рейтинг:
1

Karthik_Mahalingam

с Массив [^] является нулевым индексом, который вы должны будете рассмотреть, начиная с 0
для того, чтобы избежать Об[^] вам нужно будет проверить индекс коллекции, прежде чем обращаться к элементу указанного индекса, который вызывает исключение.

Проверить как

string msg = "";
           if (words.Length > cp)
           {
               string word = words[cp];
               var start = word.IndexOf('=') + 2;
               var length = word.Length - 1;
               if (word.Length > start)
                   msg = word.Substring(start, length);
           }


Рейтинг:
0

Dave Kreskowiak

Используя отладчик,вы можете легко понять это. установите точку останова на этой строке и запустите код. Когда код ломается, наведите курсор мыши на переменную words[cp], чтобы увидеть ее содержимое. Вы можете в значительной степени понять это там.

Либо знак " = " не найден в строке и/или длина строки не такая, как вы думаете.

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


Member 13414754

Я действительно подсчитал длину, чтобы проверить это, это правильно.

Dave Kreskowiak

"if (! words [cp] .Contains ('=') || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains (".") || words [ cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("+") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1) - 4) .Contains ("=") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("-") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("(") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4). Содержит (")") || слова [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("*") || words [cp] .Substring (12, msg .Length - 1 - msg.Length - 1 - 4) .Contains ("&") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("^ ") || слова [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("% ") || words [cp] .Substring (12, msg.Length - 1) - msg.Length - 1 - 4) .Contains ("$") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("#") || слова [cp] .Substring (12, msg.Leng th - 1 - msg.Length - 1 - 4) .Contains ("@") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("!") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("~") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("` ") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("1") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("2") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("3") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("4") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("5") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("6") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("7") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("8") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("9") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .StartsWith ("0") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains (";") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains (":") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("\\") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("/") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("\" ") || words [cp] .Substring (12, msg.Length - 1 - msg. Длина - 1 - 4). Содержит ("'") || слова [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains (".") || words [cp ] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains (",") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("{") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("}") || words [cp] .Substring ( 12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("[") || words [cp] .Substring (12, msg.Length - 1 - msg.Length - 1 - 4) .Contains ("]") || слова [cp] .Substring (12, msg.Length - 1 - msg.Length - 1-4) .Contains ("|"))"

Уххх... да. Что, черт возьми, это за с***? Я понятия не имею, что ты делаешь, но это верный признак того, что ты все делаешь неправильно.

Рейтинг:
0

Graeme_Grant

Это простая математическая ошибка. Упростите свой код и проверьте значения:

var input = "test=123";
var length = input.Length;
var start = input.IndexOf('=') + 2;
var subLength = length - 1;

Теперь, когда вы смотрите на ценности, вы получаете:
length = 8
start = 6
subLength = 7

Если вы добавите start к sublength, то получите 13 Длина текста равна 8. глядя на тестовый ввод, подзначение составляет всего 3 символа, а не 13.

Чинить:
var input = "test=123";
var start = input.IndexOf('=') + 1;
var subLength = input.Length - start;
string msg = input.Substring(start, subLength);

Теперь, что-если нет'=', вы получите еще одно исключение. Итак, чтобы исправить:
var input = "test-123";
string msg;

var start = input.IndexOf('=') + 1;
if (start > 0)
{
    var subLength = input.Length - start;
    msg = input.Substring(start, subLength);
}
else
{
    // not found!
}

Альтернативным методом было бы использование string.Split(...):
var input = "test=123";
string msg;

var parts = input.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
if (parts != null)
{
    msg = parts[parts.Length - 1];
}
else
{
    // not found!
}


Member 13414754

У меня уже есть обработчик исключений после создания переменной msg, он проверяет, используются ли недопустимые символы и нет ли знака"=",
если вам нужен полный код, просто спросите.

Graeme_Grant

Мы можем ответить только на основании того, что видим.

Рейтинг:
0

Patrice T

Цитата:
Я перепробовал все, что смог найти, но ничего не работает.

Сообщение об ошибке уже говорит вам о многом.
Вам говорят, что проблема здесь:
string msg = words[cp].Substring(words[cp].IndexOf('=') + 2, words[cp].Length - 1);

и в
Parameter name: length
   at System.String.Substring(Int32 startIndex, Int32 length)

Иначе говоря, проблема заключается в том, что слова[cp]. длина-1
Message=Index and length must refer to a location within the string.

Это означает, что подстрока должна находиться внутри исходной строки, несмотря ни на что.
вы должны это проверить:
string.Length >= string.startIndex+ Substring.length

Ты должен измениться слова[cp]. длина-1 в соответствии с той частью строки, которую вы хотите получить.

[Обновление]
Цитата:
Мне нужно иметь возможность оценить его, потому что строка будет иметь случайную длину

Нет, вы никогда не оцениваете. вы всегда знаете длину, вы знаете математику.
Заметьте, я все еще не знаю, что вы хотите сделать.
Знающая " струна.Length >= string. startIndex+ Substring.длина", максимальная подстрока.Длина-это просто применение формулы.
string.Length >= string.startIndex+ Substring.length

изменения в
string.Length- string.startIndex >= Substring.length

и
Substring.length <= string.Length- string.startIndex

Здесь нет никакой магии.


Member 13414754

Мне нужно иметь возможность оценить его, потому что строка будет иметь случайную длину

Dave Kreskowiak

ВЫ НИЧЕГО НЕ МОЖЕТЕ ОЦЕНИТЬ! Манипуляция строками никогда не работает с оценками. У вас либо есть конкретные, известные значения, либо вы получаете исключения, подобные этому.