質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

21683閲覧

なぜインデックスの配列の範囲外というエラーが出るのか理解できません

former_neet_cat

総合スコア46

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/09/28 13:31

編集2018/09/28 14:59

なぜエラーが出るのか理解したいです。

ある、本の課題をしているときに発生したエラーです。
問題のある箇所は

intarray[i] = x;

の部分で、エラー内容は、インデックスの配列の範囲外という内容でした。
その理由がわからないので教えて欲しいです。

ついでに課題内容は、
int型とint型の値の和とdouble型とdouble型の値の和を求めるメソッドをもつクラスを、オーバーロードを利用して作り、またMainメソッドからこれらのメソッドを利用して和を求めなさい。

という内容でした。
そこで、課題の内容が簡単だったので、工夫して以下の内容に挑戦して見ました。

入力した値をint型とint型の和、もしくはdouble型とdouble型の値を入力し、和を求めるメソッドを持つクラスを、オーバーロードを利用して作り、さらに、thisを利用し、Mainメソッドからこれらのこれらのメソッドを利用して和を求めるというコードに挑戦しました。

が失敗してしまいました。
その上、読みにくいコードにもなってしまいました。
読みやすく、わかりやすいコードにもしたいので、アトバイスを出来れば教えて頂けないでしょうか?
よろしくお願いします。

発生している問題・エラーメッセージ

System.IndexOutOfRangeException: "Index was outside the bounds of the array."

該当のソースコード

lang

1using System; 2 3class Overload 4{ 5 6 public void Show() 7 { 8 var ans = this; 9 Console.WriteLine("ans = {0}", ans); 10 } 11 12 public Overload(int x, int y) 13 { 14 int ans = x + y; 15 } 16 17 public Overload(double x, double y) 18 { 19 double ans = x + y; 20 } 21} 22 23class Start 24{ 25 public static void Main() 26 { 27 bool integre = false; 28 bool doublegre = false; 29 int[] intarray; 30 double[] doublearray; 31 int x = 0; 32 int y = 0; 33 double xd = 0; 34 double yd = 0; 35 36 for (int i = 0; i < 2; i++) 37 { 38 while(true) 39 { 40 Console.WriteLine("Please enter the digit"); 41 string num_str = Console.ReadLine(); 42 43 if (!Char.IsDigit(num_str[0]) && num_str[0] != '-') 44 { 45 Console.WriteLine("Incrrect input"); 46 Console.WriteLine(); 47 continue; 48 } 49 if (integre == false && doublegre == false) 50 { 51 while (true) 52 { 53 Console.WriteLine("int or double ?(1 or 2)"); 54 string select = Console.ReadLine(); 55 56 bool select_roop = false; 57 58 switch (select) 59 { 60 case "1": 61 Console.WriteLine("You selected 1"); 62 integre = true; 63 select_roop = true; 64 break; 65 66 case "2": 67 Console.WriteLine("You selected 2"); 68 doublegre = true; 69 select_roop = true; 70 break; 71 72 default: 73 Console.WriteLine("Incrrect input"); 74 break; 75 } 76 if (select_roop == true) 77 { 78 break; 79 } 80 } 81 if (integre == true) 82 { 83 intarray = new int[i]; 84 85 if (i == 0) 86 { 87 x = int.Parse(num_str); 88 intarray[i] = x; //Error 89 } 90 else if (i == 1) 91 { 92 y = int.Parse(num_str); 93 intarray[i] = y; 94 } 95 else 96 { 97 Console.WriteLine("Error"); 98 } 99 } 100 else if (doublegre == true) 101 { 102 doublearray = new double[i]; 103 104 if (i == 0) 105 { 106 xd = double.Parse(num_str); 107 doublearray[i] = xd; 108 } 109 else if (i == 1) 110 { 111 yd = double.Parse(num_str); 112 doublearray[i] = xd; 113 } 114 else 115 { 116 Console.WriteLine("Error"); 117 } 118 } 119 else 120 { 121 Console.WriteLine("Error!"); 122 } 123 } 124 break; 125 } 126 } 127 128 if (integre == true) 129 { 130 Overload ov = new Overload(x, y); 131 ov.Show(); 132 } 133 134 if(doublegre == true) 135 { 136 Overload ov = new Overload(xd, yd); 137 ov.Show(); 138 } 139 } 140} 141

上記のコードを直しても正常に動かないので修正後のコードを追記しました。

lang

1using System; 2 3class Overload 4{ 5 6 public void Show() 7 { 8 var ans = this; 9 Console.WriteLine("This ans = {0}", ans);//Ovreload display 10 } 11 12 public int Over(int x, int y) 13 { 14 int ans = (x + y); 15 return ans; 16 } 17 18 public double Over(double x, double y) 19 { 20 double ans = (x + y); 21 return ans; 22 } 23} 24 25class Start 26{ 27 public static void Main() 28 { 29 bool integre = false; 30 bool doublegre = false; 31 int[] intarray; 32 double[] doublearray; 33 int x = 0; 34 int y = 0; 35 double xd = 0; 36 double yd = 0; 37 38 for (int i = 0; i < 2; i++) 39 { 40 while (true) 41 { 42 Console.WriteLine("Please enter the digit"); 43 string num_str = Console.ReadLine(); 44 45 if (!Char.IsDigit(num_str[0]) && num_str[0] != '-') 46 { 47 Console.WriteLine("Incrrect input"); 48 Console.WriteLine(); 49 continue; 50 } 51 if (integre == false && doublegre == false) 52 { 53 while (true) 54 { 55 Console.WriteLine("int or double ?(1 or 2)"); 56 string select = Console.ReadLine(); 57 58 bool select_roop = false; 59 60 switch (select) 61 { 62 case "1": 63 Console.WriteLine("You selected 1"); 64 integre = true; 65 select_roop = true; 66 break; 67 68 case "2": 69 Console.WriteLine("You selected 2"); 70 doublegre = true; 71 select_roop = true; 72 break; 73 74 default: 75 Console.WriteLine("Incrrect input"); 76 break; 77 } 78 if (select_roop == true) 79 { 80 break; 81 } 82 } 83 } 84 else if (doublegre == true) 85 { 86 doublearray = new double[i]; 87 88 if (i == 0) 89 { 90 xd = double.Parse(num_str); 91 doublearray[i] = xd; 92 } 93 else if (i == 1) 94 { 95 yd = double.Parse(num_str); 96 doublearray[i] = xd; 97 } 98 else 99 { 100 Console.WriteLine("Error"); 101 } 102 } 103 else 104 { 105 Console.WriteLine("Error!"); 106 } 107 if (integre == true) 108 { 109 intarray = new int[2]; 110 111 if (i == 0) 112 { 113 x = int.Parse(num_str); 114 intarray[i] = x; 115 } 116 else if (i == 1) 117 { 118 y = int.Parse(num_str); 119 intarray[i] = y; 120 } 121 else 122 { 123 Console.WriteLine("Error"); 124 } 125 } 126 break; 127 } 128 } 129 130 if (integre == true) 131 { 132 Overload ov = new Overload(); 133 ov.Show(); 134 Console.WriteLine("ans = {0}",ov.Over(x, y)); 135 } 136 137 if (doublegre == true) 138 { 139 Overload ov = new Overload(); 140 ov.Show(); 141 Console.WriteLine("ans = {0}", ov.Over(x, y)); 142 143 } 144 } 145}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/28 14:04

エラーが出た際の i の値を確認できれば、なぜエラーになったかの参考になると思います。
guest

回答3

0

ベストアンサー

なんでこういうコードにしたかについては学習途中と考えて、動くように直しました。
残せるところはコメントアウトで残しましたが、ざっくり書きかえたところもあります。
いちおう、1を3回入力すれば動きますが、コメントにもあるとおり、1aとかにすると落ちますので適宜直してください

csharp

1using System; 2 3namespace ConsoleApp 4{ 5 internal class Overload 6 { 7 private readonly double ans; 8 public void Show() => Console.WriteLine($"ans = {ans}"); 9 10 public Overload(int x, int y) => ans = x + y; 11 12 public Overload(double x, double y) => ans = x + y; 13 } 14 15 class Start 16 { 17 public static void Main() 18 { 19 var integre = false; 20 var doublegre = false; 21 var intarray = new int[2]; 22 var doublearray = new double[2]; 23 //int x = 0; 24 //int y = 0; 25 //double xd = 0.0; 26 //double yd = 0.0; 27 28 for (int i = 0; i < 2; i++) 29 { 30 //while (true) //無意味 31 //{ 32 Console.WriteLine("Please enter the digit"); 33 string num_str = Console.ReadLine(); 34 35 if (!char.IsDigit(num_str[0]) && num_str[0] != '-') // 91a などを弾けない。 36 { 37 Console.WriteLine("Incrrect input"); 38 Console.WriteLine(); 39 continue; 40 } 41 //if (integre == false && doublegre == false) 42 //{ 43 while (true) 44 { 45 if (integre || doublegre) 46 { 47 break; 48 49 } 50 Console.WriteLine("int or double ?(1 or 2)"); //ユーザにとって分かりにくい、最初にintなのかdoubleなのかの問いかけをすべき。 51 string select = Console.ReadLine(); 52 53 bool select_roop = false; 54 55 switch (select) 56 { 57 case "1": 58 Console.WriteLine("You selected 1"); 59 integre = true; 60 select_roop = true; 61 break; 62 63 case "2": 64 Console.WriteLine("You selected 2"); 65 doublegre = true; 66 select_roop = true; 67 break; 68 69 default: 70 Console.WriteLine("Incrrect input"); 71 break; 72 } 73 if (select_roop) 74 { 75 break; 76 } 77 } 78 if (integre) 79 { 80 //intarray = new int[2]; 81 82 if (i == 0) 83 { 84 //x = int.Parse(num_str); 85 intarray[i] = int.Parse(num_str); //Error 86 } 87 else if (i == 1) 88 { 89 //y = int.Parse(num_str); 90 intarray[i] = int.Parse(num_str); 91 } 92 else 93 { 94 Console.WriteLine("Error"); 95 } 96 } 97 else if (doublegre) 98 { 99 //doublearray = new double[2]; 100 101 if (i == 0) 102 { 103 //xd = double.Parse(num_str); 104 doublearray[i] = double.Parse(num_str); 105 } 106 else if (i == 1) 107 { 108 //yd = double.Parse(num_str); 109 doublearray[i] = double.Parse(num_str); 110 } 111 else 112 { 113 Console.WriteLine("Error"); 114 } 115 } 116 else // このelseに到達することはない 117 { 118 Console.WriteLine("Error!"); 119 } 120 //} 121 //} 122 } 123 124 if (integre) 125 { 126 //Overload ov = new Overload(x, y); 127 //ov.Show(); 128 new Overload(intarray[0], intarray[1]).Show(); 129 } 130 131 if (doublegre) 132 { 133 //Overload ov = new Overload(xd, yd); 134 //ov.Show(); 135 new Overload(doublearray[0], doublearray[1]).Show(); 136 } 137 138 Console.ReadKey(); 139 } 140 } 141} 142

---追記
やろうとしていることはオーバーロードってより、ジェネリクスで実現したほうがいいように思います(学習ってことを考えると継承でもいいのかも?どっちにしてもオーバーロードだと課題にあってない気がする)。随所にisInt(旧integre)が出てくるのがその原因。そのせいで、インデントが多すぎる、良くないコードになってしまっている。
とりあえず着想をかえない範囲で修正しました。
intかどうかの質問を前にだし、変数を減らして、数のチェックをやって、変数名を整えました。
今の学習段階でもこれくらいになるといいのかなと思います。

csharp

1using System; 2 3namespace ConsoleApp3 4{ 5 internal class Overload 6 { 7 private readonly double ans; 8 public void Show() => Console.WriteLine($"ans = {ans}"); 9 10 public Overload(int x, int y) => ans = x + y; 11 12 public Overload(double x, double y) => ans = x + y; 13 } 14 15 class Start 16 { 17 public static void Main() 18 { 19 var isInt = false; 20 var isDouble = false; 21 var intArray = new int[2]; 22 var doubleArray = new double[2]; 23 var x = 0; 24 var xd = 0.0; 25 26 while (!isInt && !isDouble) 27 { 28 Console.WriteLine("int or double ?(1 or 2)"); 29 var select = Console.ReadLine(); 30 31 switch (select) 32 { 33 case "1": 34 Console.WriteLine("You selected 1"); 35 isInt = true; 36 break; 37 38 case "2": 39 Console.WriteLine("You selected 2"); 40 isDouble = true; 41 break; 42 43 default: 44 Console.WriteLine("Incorrect input"); 45 break; 46 } 47 } 48 49 for (var i = 0; i < 2; i++) 50 { 51 Console.WriteLine("Please enter the digit"); 52 var numStr = Console.ReadLine(); 53 54 if (isInt ? !int.TryParse(numStr, out x) : !double.TryParse(numStr, out xd)) 55 { 56 Console.WriteLine("Incorrect input"); 57 i--; 58 continue; 59 } 60 if (isInt) 61 { 62 intArray[i] = x; 63 } 64 if (isDouble) 65 { 66 doubleArray[i] = xd; 67 } 68 } 69 if (isInt) 70 { 71 new Overload(intArray[0], intArray[1]).Show(); 72 } 73 if (isDouble) 74 { 75 new Overload(doubleArray[0], doubleArray[1]).Show(); 76 } 77 Console.ReadKey(); 78 } 79 } 80}

投稿2018/09/28 14:36

編集2018/09/28 15:15
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2018/09/28 14:38

ちなみに、そもそも配列の個数が2個なのがあらかじめ分かっているのに初期化をiでやったのが間違いの原因ですが、そこだけ直しても動作しないので、まあ色々見比べてくださいな。
former_neet_cat

2018/09/28 14:53

ありがとうございます! 確かに自分で配列を直した時正常に動かずに修正してました。 その修正後のコードと見比べて、直していきます。
papinianus

2018/09/28 15:15

個人的に許せる限度まで、修正しました、参考になれば幸いです。
guest

0

↓ここしか読まずに回答します

csharp

1 intarray = new int[i]; // -> 1. 2 3 if (i == 0) 4 { 5 x = int.Parse(num_str); 6 intarray[i] = x; //Error // -> 2. 7

2.に進むとき、iは0なのですから、1.において、intarrayの個数は0個と宣言されています。
つまり、intarrayの1個目の要素intarray[0]は確保されていません。

配列の要素(0個)より多い番地である1個目を利用しようとすれば、範囲外のエラーがでても仕方ないです。

投稿2018/09/28 14:06

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

その課題内容から,この長大なコードが生まれた経緯がわかりませんが…

とりあえずエラー要因に関しては,そのエラーが発生する際の配列のサイズを考えてみるとよいかと.

投稿2018/09/28 14:04

fana

総合スコア11632

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

former_neet_cat

2018/09/28 14:54

確かに、配列の値を[0]と指定してました・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問