Многочисленные исключения во время выполнения при использовании строкового массива в C# по неизвестной причине - PullRequest
0 голосов
/ 27 апреля 2020

Я пишу лексер или токенизатор для языка программирования. Одна из основных функций - разбить строку исходного кода на «токены». Я достигаю этого, разбивая пробелы для создания строковых массивов. Поэтому, когда я хочу сохранить строки, я должен временно изменить содержимое на ключевое слово, пока строка разбита, а затем снова вставить строки обратно. Это работало до тех пор, пока я не разработал систему переменных для языка, и мне нужно было сохранять несколько строк. Тогда все исключения ада вырвались на свободу.

Исключения:

NullReferenceException (строка 12) subStringArg[ini] = quotes[1];

IndexOutOfRangeException (строка 34) value = value.Replace("STRING", subStringArg[ini]);

Минимум Воспроизводимый пример:

public static string[] LexLine(string line)
        {
            string[] subStringArg = null;
            string[] quotes = null;
            string[] tokens = null;
            int ini = 0; // Random name
            while (line.Contains('\"'))
            {
                if (line.Contains('\"'))
                {
                    quotes = line.Split('\"');
                    subStringArg[ini] = quotes[1];
                }

                if (subStringArg != null)
                {
                    line = line.Replace(quotes[1], "STRING");
                    line = line.Replace("\\", "");
                    line = line.Replace("\"", "");
                }
                ini++;
            }
            tokens = line.Split(' ');
            if (tokens[0] == "Output" && tokens[1] != "STRING")
            {
                tokens[1] = IO.OutputVariable(tokens[1]);
            }
            ini = 0;
            foreach (string i in tokens)
            {
                if (i == "STRING" && subStringArg != null)
                {
                    string value = i;
                    value = value.Replace("STRING", subStringArg[ini]);
                    tokens[currentArrayEntry] = value;
                }
                currentArrayEntry++;
                ini++;
            }
            return tokens;
        }

Исходный код (из моего языка):

Output "Defining variables..." to Console. // Exception thrown here
New string of name "sampleStringVar" with value "sample".
Output "enter your name:" to Console.
Get input.
Output sampleStringVar to Console.

Я спрашиваю здесь, потому что я не знаю, что делать. Я не должен получать NullReferenceException от присваивания значений.

1 Ответ

2 голосов
/ 27 апреля 2020

Вы устанавливаете следующее

string[] subStringArg = null;

, а затем делаете это

subStringArg[ini] = quotes[1];

Но вы не инициализировали subStringArg, поэтому он по-прежнему нулевой, поэтому вы не можете назначить что-нибудь к нему, и вы получите NullReferenceError

Вы должны сначала инициализировать свой массив, прежде чем вы можете что-либо присвоить ему.

Кроме того, вы не должны предполагать, что у вас есть значение в quotes[1] без предварительной проверки. Это приведет к IndexOutOfRangeException

в качестве другого пункта. Первый оператор If внутри вашего while l oop проверяет то же условие, что и while l oop, поэтому он всегда будет верным!

Так что лучше было бы следующее

string[] subStringArg = new String[enterKnownLengthHere_OrUseALIst];
...
 while (line.Contains('\"'))
 {
        quotes = line.Split('\"');
        if(quotes != null && quotes.Length >= 2)
            subStringArg[ini] = quotes[1];
        else
           //Error handling here!


        if (subStringArg.Length >= 1)
        {
                line = line.Replace(quotes[1], "STRING");
                line = line.Replace("\\", "");
                line = line.Replace("\"", "");
        }
        ini++;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...