DOBON.NET DOBON.NETプログラミング掲示板過去ログ

インデックスが配列の境界外ですという例外について

環境/言語:[Windows XP VS C# 2010 Express]
分類:[.NET]

よろしくお願いします。
以下のソースコードをビルドするとエラーはないのですが、実行すると
タイトルのような例外が発生します。
読み込みたいcsvファイルは2列15行なのですがこれは実装に問題があるということなのでしょうか?
ご教授していただけたら幸いと思い質問させていただきます。
よろしくお願いします。

↓メイン部分
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 配列
{
    class Program
    {
        static void Main(string[] args)
        {
            string FileName = "C:\\15ポイントデータ.csv";
            string encod = "shift_jis";
            DataClass[] table = ReadCSV(FileName, encod);
        }

        static DataClass[] ReadCSV(string FileName, string encod)
        {
            System.IO.StreamReader sr = null;
            try
            {
                System.Text.Encoding EncoObj = System.Text.Encoding.GetEncoding(encod);
                sr = new System.IO.StreamReader(new System.IO.FileStream(FileName, System.IO.FileMode.Open), EncoObj);
                string text = sr.ReadToEnd();

                //行単位に分離して配列に格納
                string[] line = text.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);

                string[] StrArryData = new string[5];
                DataClass[] table = new DataClass[line.Length];

                for (int i = 1; i <= line.Length; i++)
                {
                    //行単位に分離して配列に格納
                    StrArryData = line[i].Split(',');

                    //各種の列要素のデータを確保
                    table[i] = new DataClass();
                    double.TryParse(StrArryData[0], out table[i].dataArry1);
                    double.TryParse(StrArryData[1], out table[i].dataArry2);
                }

                return table;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            finally
            {
                if (sr != null)
                    sr.Close();
            }
            return null;
        }
    }
}

↓配列部分
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 配列
{
    public class DataClass
    {
        public double dataArry1 = new double();
        public double dataArry2 = new double();

        
    }
}
■No27863に返信(としおさんの記事)
> string[] StrArryData = new string[5];
  string[] StrArryData;
で充分かと思います。

最初に 5個の要素を生成しておいたところで、そのあとの
>     //行単位に分離して配列に格納
>     StrArryData = line[i].Split(',');
の段階で、それらを捨てて新しい配列を割り当て直しているため、
最初に要素を確保しておいても意味がありません。


> for (int i = 1; i <= line.Length; i++)
これが問題かと。
たとえば、line.Length が 3 だとしたら、配列 line は
 line[0]
 line[1]
 line[2]
という、3 つの要素を持つ事になりますね。

しかし提示の for は、「i <= 3 の間はループを続ける」という条件なので、
 1回目 : i = 0
 2回目 : i = 1
 3回目 : i = 2
 4回目 : i = 3
 5回目は実行されずにループ終了
となります。そのため、i が 3 の時には line[i] にアクセスできません。
■No27864に返信(魔界の仮面弁士さんの記事)
> しかし提示の for は、「i <= 3 の間はループを続ける」という条件なので、
>  1回目 : i = 0
>  2回目 : i = 1
>  3回目 : i = 2
>  4回目 : i = 3
>  5回目は実行されずにループ終了
> となります。そのため、i が 3 の時には line[i] にアクセスできません。

揚げ足をとるようで申し訳ないですが、このコードの罠は i = 1 スタートなことですね。
なので、この部分は以下のように読み替えてください。

1回目 : i = 1
2回目 : i = 2
3回目 : i = 3
4回目は実行されずにループ終了
■No27864に返信(魔界の仮面弁士さんの記事)
> ■No27863に返信(としおさんの記事)
>>string[] StrArryData = new string[5];
> string[] StrArryData;
> で充分かと思います。
>
> 最初に 5個の要素を生成しておいたところで、そのあとの
>> //行単位に分離して配列に格納
>> StrArryData = line[i].Split(',');
> の段階で、それらを捨てて新しい配列を割り当て直しているため、
> 最初に要素を確保しておいても意味がありません。
>
>
>>for (int i = 1; i <= line.Length; i++)
> これが問題かと。
> たとえば、line.Length が 3 だとしたら、配列 line は
>  line[0]
>  line[1]
>  line[2]
> という、3 つの要素を持つ事になりますね。
>
> しかし提示の for は、「i <= 3 の間はループを続ける」という条件なので、
>  1回目 : i = 0
>  2回目 : i = 1
>  3回目 : i = 2
>  4回目 : i = 3
>  5回目は実行されずにループ終了
> となります。そのため、i が 3 の時には line[i] にアクセスできません。
大変初歩的なことをお聞きしてすいませんでした。
ご指摘の通りにしてみたところ無事解決しました。
またよろしくお願いします。
■No27867に返信(Azuleanさんの記事)
> ■No27864に返信(魔界の仮面弁士さんの記事)
>>しかし提示の for は、「i <= 3 の間はループを続ける」という条件なので、
>> 1回目 : i = 0
>> 2回目 : i = 1
>> 3回目 : i = 2
>> 4回目 : i = 3
>> 5回目は実行されずにループ終了
>>となります。そのため、i が 3 の時には line[i] にアクセスできません。
>
> 揚げ足をとるようで申し訳ないですが、このコードの罠は i = 1 スタートなことですね。
> なので、この部分は以下のように読み替えてください。
>
> 1回目 : i = 1
> 2回目 : i = 2
> 3回目 : i = 3
> 4回目は実行されずにループ終了

補足してくださってありがとうございます。
またよろしくお願いします。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板