当索引在边界内时,索引越界

本文关键字:索引 越界 边界 | 更新日期: 2023-09-27 18:13:00

当我请求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;

++++++++++++++++++++++++++++++++++++++++++++++

找到问题!!!!!!

基本上,我昨天工作过度了,所以我的大脑在一天结束的时候被炸了,我很易怒。函数代码工作得很好,除非像许多人说的那样,notes字符串是空的。我知道notes字符串不是空的,因为它在for循环中没有+1部分就可以发布。但我忘了一件事。发送到表单的第一个"item"是程序中数组中的第一个"item"。尽管所讨论的条目注释确实有17个单词,但它是列表中的第二个条目。当应用程序加载时,列表中的第一个项目会被发布,我只需滚动到包含17个单词注释的项目。第一个发布的条目没有注释,所以第一次调用这个函数时,参数是一个空字符串。哦!感觉愚蠢的

谢谢大家! !我很感激你花时间帮我纠正我的错误。哈哈

当索引在边界内时,索引越界

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

首先注意:

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

给出一个EMPTY数组,其中words.Count == 0。特别注意,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,这意味着它不迭代

如果words为空,则得到words。计数-1 意味着-1,你怎么做:

words.elementAt(-1);

注意下面的代码:

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

当注释为空时,您添加到words列表?like notes[idx] == ' '

在添加它之前是否会测试它是否为空?

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

只是猜测。

原始文章:

在执行elementAt之前先检查计数,因此,而不是:

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

Do like:

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

如果你用messagebox来检查它可能会很好,只是为了调试如果计数真的是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) + ' '; }

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

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

当你给单词加上+1时。Count,那么它就会超出数组的边界。

总而言之,这是一种真正的围绕(和错误填充)划分音符的方式。

我使用了以下测试代码:
        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;

对不起,你完全错了。

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

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();
        }
    }
}