0

I'm getting an index out of bounds error when I request the last element in the list for a C# Windows Form Application.

Does anyone know what might be causing this because it literally makes no sense whatsoever. It's as if the computer is miscalculating. The size is supposedly 17, but everything above index 5 gives an error. Once logic goes out the window, I've got nothing left. Perhaps there's something weird going on behind the scenes that someone else may have encountered before?

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;

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

FOUND THE PROBLEM!!!!!!

Basically, I overworked myself yesterday so my brain was fried by the end of the day and I was irritable. The function code works just fine unless, like many have said, the notes string is empty. I knew that the notes string wasn't empty because it posts just fine without the +1 portion in the for-loop. BUT I FORGOT ABOUT ONE THING. The first 'item' that gets posted to the form is the first 'item' in the array I have in my program. Even though the item notes in question do indeed have 17 words, it's the second item in the list. The first item in the list gets posted when the application loads and I simply scroll over to the item with the 17 word notes. The first item that's posted doesn't have notes so the first time that function is called, the argument is an empty string. OOPS! feels dumb

Thanks, everyone!! I appreciate you taking the time to help fix my nonsense here. haha

4

5 に答える 5

3

エラーはかなり簡単で、すべての症状を説明できます。

まず、次のことに注意してください。

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

の EMPTY 配列が得られますwords.Count == 0words.ElementAt(0)特に、スローすることに注意してください。

この行でOKです(これはスローします):

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 ループは while をk < 0実行するため、ループは 1 回の繰り返しも実行しません。

今これ:

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

このループは whileで実行されるため、 でk < 11 回実行され、配列が空であるためスローされます。k=0ElementAt(0)

ついに:

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

繰り返しますが、これは一度も繰り返されません。words.Countは 0 なので、 while 実行さk < 0れます。つまり、繰り返されません。

于 2013-05-10T23:12:18.437 に答える
1

words が空の場合、words.Count - 1は -1 を意味します。どうすればよいですか:

words.elementAt(-1);
于 2013-05-10T22:50:13.533 に答える
1

コードにスペースが 1 つしか含まれていない場合、配列には 1 つの単語しかありません。

one_thirdandの結果は、 two_thirdsIFwords.Countが 3 未満の場合は常にゼロになります。これは、コードの残りの部分がそれらを見つけられないことを意味します。

+1 を words.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;
于 2013-05-10T23:32:48.197 に答える
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正しく設定されている場合、コードは機能します。

notes2x2x5 ではなく 3x3x3 に分割するには、末尾にスペースが必要であることに注意してください。

コードの簡略化された形式は...

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();
        }
    }
}
于 2013-05-11T00:00:59.693 に答える
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) : "";

アップデート:

あなたの投稿から得た以下のコードを使用して、自分の PC でサンプリングを行いましたが、エラーは発生しませんでした。マルチスレッドを使用していて、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) + ' '; }
于 2013-05-10T22:57:23.643 に答える