【问题标题】:Multiple runtime exceptions when using string array in C# for unknown reason由于未知原因在 C# 中使用字符串数组时出现多个运行时异常
【发布时间】:2020-04-27 04:15:04
【问题描述】:

我正在为编程语言编写词法分析器或标记器。主要功能之一是将源代码行拆分为“令牌”。我通过分割空间来创建字符串数组来实现这一点。因此,当我想保留字符串时,我必须在分割行时将内容临时更改为关键字,然后再将字符串放回。这一直有效,直到我为该语言开发了变量系统,并且我必须能够保留多个字符串。然后所有异常都崩溃了。

例外:

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.

我在这里问是因为我不知道该怎么做。我不应该从 assigning 值中得到 NullReferenceException。

【问题讨论】:

  • 你在哪里初始化subStringArg
  • 我觉得是时候让你学会调试了。在 YouTube 上观看几个视频,以掌握单步调试代码的窍门。第一个错误:NullReferenceException 是因为 subStringArg[ini] 尚未初始化。第二个错误 IndexOutOfRangeException 是因为 subStringArg[ini] 是一个数组,其项数少于 ini 值。
  • 不是我初始化的地方,我将quotes[1] 的值分配给subStringArg[ini]。另外我必须澄清一下,当我调试时,quotes[1] 的值是有值的。
  • C# 中的 Jeremy 可以在不初始化的情况下添加数组中的值。我还在第 34 行之前确定了ini = 0。当抛出异常时,quotes[1] 不为空,唯一的空变量是subStringArgtokens,以及ini = 0

标签: c# nullreferenceexception lexer indexoutofrangeexception


【解决方案1】:

你设置了以下

string[] subStringArg = null;

然后你再做这个

subStringArg[ini] = quotes[1];

但是你还没有初始化subStringArg,所以它仍然是空的,所以你不能给它分配任何东西,你会得到一个NullReferenceError

您必须先初始化您的数组,然后才能将任何内容分配给它。

另外,你不应该假设你在quotes[1] 中有一个值而不先检查它。这将导致IndexOutOfRangeException

另外一点。 while 循环中的第一个 If 语句检查与 while 循环相同的条件,所以它总是正确的!

所以下面会更好

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++;
    }

【讨论】:

  • 不错的答案,OP 我仍然强烈建议您学习如何使用调试器,IDE 向您展示了这一点。你不知道自己错过了什么!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2022-08-08
  • 2017-05-22
  • 1970-01-01
相关资源
最近更新 更多