出于未知原因在 C# 中使用字符串数组时出现多个运行时异常
Multiple runtime exceptions when using string array in C# for unknown reason
我正在为一种编程语言编写词法分析器或分词器。主要功能之一是将源代码行拆分为"tokens"。我通过拆分空间来创建字符串数组来实现这一点。因此,当我要保留字符串时,必须在分行时临时将内容更改为关键字,然后再将字符串放回原处。这一直有效,直到我为该语言开发了变量系统,并且我必须能够保留多个字符串。然后所有异常都崩溃了。
例外情况:
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。
你设置如下
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++;
}
我正在为一种编程语言编写词法分析器或分词器。主要功能之一是将源代码行拆分为"tokens"。我通过拆分空间来创建字符串数组来实现这一点。因此,当我要保留字符串时,必须在分行时临时将内容更改为关键字,然后再将字符串放回原处。这一直有效,直到我为该语言开发了变量系统,并且我必须能够保留多个字符串。然后所有异常都崩溃了。
例外情况:
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。
你设置如下
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++;
}