当我请求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! 感到愚蠢
谢谢大家!我感谢您花时间帮我修复我的废话。哈哈
答案 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_third
和two_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();
}
}
}