当索引在边界内时,索引越界
本文关键字:索引 越界 边界 | 更新日期: 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_third
和two_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();
}
}
}