当它在界限时索引越界

时间:2013-05-10 22:48:22

标签: c# .net list

当我请求C#Windows窗体应用程序列表中的最后一个元素时,我得到一个索引超出范围错误。

有谁知道可能导致这种情况的原因,因为它根本没有任何意义。就好像计算机计算错误一样。大小应该是17,但是索引5以上的所有内容都会出错。一旦逻辑走出窗外,我什么都没有了。也许在其他人可能遇到过的幕后会发生一些奇怪的事情?

List<string> words = new List<string>();

        List<string> words = new List<string>();
        string word = "";
        int idx = 0;
        while (idx < notes.Length)
        {
            word += notes[idx];
            if (notes[idx] == ' ')
            {
                words.Add(word);
                word = "";
            }
            ++idx;
        }
        string notes1 = "";
        string notes2 = "";
        string notes3 = "";

        int one_third = words.Count / 3;
        int two_thirds = (words.Count / 3) * 2;

        int k;
        for (k = 0; k < one_third; k++)
            notes1 += words.ElementAt(k) + ' ';
        for (k = one_third; k < two_thirds; k++)
            notes2 += words[k] + ' ';
        for (k = two_thirds; k < words.Count; k++)
            notes3 += words[k] + ' ';

        notesLabel1.Text = notes1;
        notesLabel2.Text = notes2;
        notesLabel3.Text = notes3;

++++++++++++++++++++++++++++++++++++++++++++++ < / p>

发现问题!!!!!!

基本上,我昨天过度劳累,所以我的大脑在一天结束时被炸了,我很烦躁。函数代码工作得很好,除非像许多人说的那样,注释字符串是空的。我知道音符字符串不是空的,因为它在for循环中没有+1部分就发布得很好。但我忘了一件事。发布到表单的第一个“项目”是我在程序中的第一个“项目”。即使有问题的项目确实有17个单词,它也是列表中的第二个项目。列表中的第一项在应用程序加载时发布,我只需滚动到包含17个单词备注的项目。发布的第一个项目没有注释,因此第一次调用该函数时,参数为空字符串。 OOPS! 感到愚蠢

谢谢大家!我感谢您花时间帮我修复我的废话。哈哈

5 个答案:

答案 0 :(得分:3)

错误相当简单,我们可以解释所有症状。

首先请注意:

List<string> words = new List<string>();

为您提供words.Count == 0的EMPTY数组。特别要注意words.ElementAt(0)会抛出。

好的,这一行(抛出):

string the_word = words.elementAt(words.Count - 1);

显然(words.Count - 1)-1因此错误。

以下代码不会抛出错误:

for (k = 0; k < words.Count / 3; k++) notes1 += words.ElementAt(k) + ' ';

因为for循环在k < 0运行,所以循环甚至不执行单次迭代。

现在这一个:

for (k = 0; k < words.Count / 3 + 1; k++) notes1 += words.ElementAt(k) + ' ';

此循环将在k < 1运行,因此它将使用k=0执行一次,因此ElementAt(0)将抛出,因为数组为空。

最后:

for (k = 0; k < words.Count; k++) notes1 += words.ElementAt(k);

再次,这不会迭代一次。 words.Count为0,因此它在k < 0时运行,这意味着它不会迭代。

答案 1 :(得分:1)

如果单词为空,则表示 words.Count - 1 表示-1,您怎么做:

words.elementAt(-1);

答案 2 :(得分:1)

注意代码中的代码如下:

if (notes[idx] == ' ')
        {
            words.Add(word);
            word = "";
        }

当笔记为空时,您会添加到words列表中吗?比如notes[idx] == ' '

在添加它之前是否可以测试它是否为空,例如?

if (!String.IsNullOrEmpty(notes[idx]))
        {
            words.Add(word);
            word = "";
        }

猜猜。

原帖:

在执行elementAt之前先检查计数,所以代替:

 string the_word = words.elementAt(words.Count - 1);

喜欢:

 string the_word = words.Count>0 ? words.elementAt(words.Count - 1) : "";

如果您使用消息框检查它只是为了调试,如果计数真的是17,那么可能会很好:

 MessageBox.Show(words.Count);
 string the_word = words.Count>0 ? words.elementAt(words.Count - 1) : "";

<强>更新

我在自己的电脑上做了一个采样,下面的代码来自你的帖子,它没有错误。您是否正在使用多线程并尝试更改words列表的值?

 List<string> words = new List<string>();
        String notes1="";

        int k;
        words.Add("The quick brown fox jumps over the lazy dog.");
        string the_word = words.ElementAt(words.Count - 1);
        MessageBox.Show(the_word);

        for (k = 0; k < words.Count / 3; k++)
        { notes1 += words.ElementAt(k) + ' '; }


        for (k = 0; k < words.Count / 3 + 1; k++)
        { notes1 += words.ElementAt(k) + ' '; }

答案 3 :(得分:1)

如果您的代码只包含一个空格,那么它在数组中只有一个单词。

one_thirdtwo_thirds的结果将始终为零,如果words.Count小于3.这意味着您的其余代码将永远找不到它们。

当你为words.count添加+1时,它将超出数组的范围。

总而言之,这是一个非常圆的(和错误填充)分裂音符的方式。

<强>更新

我使用了以下测试代码:

        Char[] notes = "there are seventeen words in this list make the most of them because it really counts here".ToCharArray();

        List<string> words = new List<string>();
        string word = "";
        int idx = 0;
        while ( idx < notes.Length ) {
            word += notes[idx];
            if ( notes[idx] == ' ' ) {
                words.Add(word);
                word = "";
            }
            ++idx;
        }
        string notes1 = "";
        string notes2 = "";
        string notes3 = "";

        int one_third = words.Count / 3;
        int two_thirds = ( words.Count / 3 ) * 2;
        int k;

        for ( k = 0; k < one_third +1; k++ )
            notes1 += words.ElementAt(k) + ' ';

        for ( k = one_third; k < two_thirds; k++ )
            notes2 += words[k] + ' ';

        for ( k = two_thirds; k < words.Count; k++ )
            notes3 += words[k] + ' ';

        MessageBox.Show(notes1);

并且没有错误。结果并不完全是您通常所期望的,但没有错误。请注意,我输入了+1所述的问题。


实现此目标的另一种方法是:

    String notes = "there are seventeen words in this list make the most of them because it really counts here";

    Int32 one_third = notes.Trim().Split(' ').Count() / 3 + 1;
    String matchString = @"^(\w+\b.*?){" + one_third.ToString() + "}";

    String notes1 = Regex.Match(notes, matchString).ToString();
    notes = notes.Remove(0, notes1.Count()).Trim();

    String notes2 = Regex.Match(notes, matchString).ToString();
    notes = notes.Remove(0, notes2.Count()).Trim();

    String notes3 = notes;

答案 4 :(得分:1)

抱歉,但你错了。

新控制台应用程序中的以下代码输出:

Some  nine  word
note  which  I'm
stretching  here  now

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StackOverflow16491866 {
    class Program {
        static void Main(string[] args) {
            string notes = "Some nine word note which I'm stretching here now ";
            List<string> words = new List<string>();
            string word = "";
            int idx = 0;
            while (idx < notes.Length) {
                word += notes[idx];
                if (notes[idx] == ' ') {
                    words.Add(word);
                    word = "";
                }
                ++idx;
            }
            string notes1 = "";
            string notes2 = "";
            string notes3 = "";

            int one_third = words.Count / 3;
            int two_thirds = (words.Count / 3) * 2;

            int k;
            for (k = 0; k < one_third; k++)
                notes1 += words.ElementAt(k) + ' ';
            for (k = one_third; k < two_thirds; k++)
                notes2 += words[k] + ' ';
            for (k = two_thirds; k < words.Count; k++)
                notes3 += words[k] + ' ';

            Console.WriteLine(notes1);
            Console.WriteLine(notes2);
            Console.WriteLine(notes3);
            Console.ReadLine();

        }
    }
}

简而言之,正确填充notes后,您的代码就可以使用。

请注意,它需要notes中的尾随空格分成3x3x3而不是2x2x5

代码的简化形式是......

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StackOverflow16491866 {
    class Program {
        static void Main(string[] args) {
            string Notes = "Some nine word note which I'm stretching here now";
            List<string> Words = Notes.Split(' ').ToList();
            int WordsPerLine = (int)Words.Count/3;
            string Note1 = string.Join(" ", Words.GetRange(0, WordsPerLine));
            string Note2 = string.Join(" ", Words.GetRange(WordsPerLine, WordsPerLine));
            string Note3 = string.Join(" ", Words.GetRange(WordsPerLine * 2, Words.Count - WordsPerLine * 2 - 1));
            Console.WriteLine("{0}\n{1}\n{2}", Note1, Note2, Note3);
            Console.ReadLine();
        }
    }
}