System.ArgumentOutOfRangeException:索引和长度必须引用字符串中的位置

问题描述 投票:0回答:5

当我在 Visual Studio 上执行代码时,它运行良好,但是当我执行 exe 文件时,它抛出异常。

System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex, Int32 length)
 at QuoteExtractor.frmQuoteExtractor.cmdProcess_Click(Object sender, EventArgs e)

我的代码

    private void cmdProcess_Click(object sender, EventArgs e)
    {
        try
        {

            foreach (string line in rtfMain.Lines)
            {
                try
                {
                    if (line.Trim() != "")
                    {
                        if ((line != "") && (line != " ") && (line.Substring(0, 3) != "***") && (line.Substring(0, 5) != "CUSIP"))
                        {
                            Quote q = new Quote();
                            q.Parse(line);
                            DisplayQuote(q);
                            QuoteList.Add(q);
                        }
                    }
                }

输入:

   *** 9:30 AM ***    
   CUSIP          BOND NAME              SIZE       CURR FACE     TALK        COVER PX 
   004421GU1     ACE 2004-HE2 M2       10.000MM     1.103MM               dnt, 90 rsrv
   61744CTZ9     MSHEL 2005-3 M3       4.720MM      4.720MM               dnt
c# .net
5个回答
17
投票

阅读错误消息。1其中之一

line.Substring(0, 3) != "***"

line.Substring(0, 5) != "CUSIP"

不好,因为

line
的长度分别小于 3 或 5。另外,请使用
String.StartsWith
来实现此目的。

1:错误消息实际上是在向你尖叫:

System.ArgumentOutOfRangeException
Index
length
必须引用字符串中的位置。参数名称:
length
at
System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at
System.String.Substring(Int32 startIndex, Int32 length)

您传递给 length

String.Substring
 论点存在问题,这一点再清楚不过了。来自文档

例外情况

ArgumentOutOfRangeException

startIndex
length
表示不在该实例内的位置。

-或-

startIndex
length
小于零。

您的

startIndex
值不小于零。您的
length
值不小于零。这就排除了第二种可能。第一种可能性是
startIndex
length
表示不在字符串内的位置。您的
startIndex
值为零,因此
startIndex
length
等于
length
。因此错误消息告诉您
length
指的是不在字符串内的位置。因此,
length
超过字符串的长度。它不能再清楚了。


4
投票

如果您不知道字符串是否确实包含足够的字符用于子字符串,则应使用 StartsWith 进行比较。


0
投票

例外的是你在

上这么说
line.Substring(0, 3) != "***"

或开

line.Substring(0, 5) != "CUSIP"

您引用的字符串位置不存在,可能是因为

line
值长度小于预期。

另一段代码可能是......

private void cmdProcess_Click(object sender, EventArgs e)
{
    foreach (string line in rtfMain.Lines)
    {
        if (!string.IsNullOrEmpty(line.Trim()) 
                        && !line.StartsWith("***") 
                        && !line.StartsWith("CUSIP"))
        {
            Quote q = new Quote();
            q.Parse(line);
            DisplayQuote(q);
            QuoteList.Add(q);
        }
    }
}

0
投票

我对附加代码也有同样的问题 - 如果“line”字符串少于 57 个字符,VS 不会捕获错误。它也不对测试代码做出反应 - 该代码来自我在 VS 的另一个并发实例中创建的测试项目,其中调试器确实捕获了错误。如果我将代码放在主项目中的 try-catch 中,它确实会收到错误。

我以前见过它一次,怀疑它要么是 Visual Studio 中的一个错误(在这种情况下是 2008 Pro - 不知道它是否影响更高版本,刚刚升级到 VS 2013,但还没有在那里看到它)或导致由损坏的项目文件造成。

        while (rf.Peek() >= 0)
        {
            line = rf.ReadLine().Trim();

            MessageBox.Show(line.Length.ToString());

            // test
            string x = "abc";
            string y = x.Substring(0, 20);
            // end test

            if (line.Substring(0, 57) == "<td align=\"right\" nowrap=\"nowrap\"><span       class=\"currency\">")
            {
                break;
            }

            // some more code 
        }

0
投票

我用这个来检查名字中的第二个字母:

line.Substring(1, 1)

只输入一个字母,这个 C# 函数就失败了。我用 try / catch 块发现了它,请参阅 是否有更简单的方法仅在发生错误时才在断点处停止? - 堆栈溢出

然后我知道长度“1”可能会发生,这对数据来说是新的。

我解决了这个问题:

if (line.Length > 1) 
{
    ...
} else {
...
}

您也可以这样做并要求

line.Length > 4

© www.soinside.com 2019 - 2024. All rights reserved.