• 締切済み

Visual C++ 2008 EEでボタンの判定、結果を配列に格納

OSはXPでViaual C++ 2008 Express EditionのWindowsフォームアプリケーションにて一つのフォームで全132問に答えるというものを作成しています。フォームには[戻る]、[次へ進む]、[チェック除外]ボタンと「はい」、「いいえ」、「どちらでもない」のラジオボタン、問題文とタイマーのラベル、テキストボックス(問題番号を入力すると[戻る]ボタンが[移動]ボタンに変わり、入力した問題に進む)があります。最初に変数qに1を入れ、[次へ進む]を押すとqに1がプラスされswitch文で2問以降に進む(ラベルのみ切り替わる)というもので、最後の問題に行くと[次へ進む]ボタンが[終了]ボタンに変わります。ただし、全ての問題に解答していなければ終了できないようにしています。この解答結果をCSVに(はいなら1、いいえなら2、どちらでもないなら3)出力したいと考えているのですが、ラジオボタンにチェックを入れ、[次へ進む]ボタンを押したときのみ「インデックスが配列の境界外です」というエラーが表示されてしまいます。コードは以下の通りですが、どこを直せばよいのか分からないのでご教授願います。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { endflag = 0; this->button2->Text = "次へ進む"; if(flag == 1){ q = jump; flag = 0; this->button1->Text = "戻る"; this->textBox1->Text = ""; }else{ q--; } if(q == 1){ this->button1->Enabled = false; } switch(q){ case 1:                          ・                          ・                          ・                          case 132                           endflag = 1; break; }                            }: private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { String^ s = rtrstrg(); if(endflag == 1){ if(s == "") { MessageBox::Show("全ての質問に答えて下さい。","エラー"); } else if(MessageBox::Show("終了しますか?", "確認", MessageBoxButtons::OKCancel, MessageBoxIcon::Question) == System::Windows::Forms::DialogResult::OK) { this->Close(); } } q++; this->button1->Enabled = true; switch(q){ case 2:                      ・                      ・                      ・                      case 132                       endflag = 1;    break; }                      }: private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { this->radioButton1->Checked = false; this->radioButton2->Checked = false; this->radioButton3->Checked = false; } private: System::Void chg(System::Object^ sender, System::EventArgs^ e) { bool result = int::TryParse(textBox1->Text, jump); if(jump > 0 && jump <= 132){ if(jump != q){ this->button1->Text = "移動"; this->button1->Enabled = true; flag = 1; } } else{ textBox1->Text = ""; this->button1->Text = "戻る"; flag = 0; } } private: System::String^ rtrstrg() { String^ s; for(int i=1; i<=QSTNB; i++) { s += this->rtrdt(i); if(s->EndsWith("×")) { return ""; } } return s->Remove(s->Length - 1); } private: System::String^ rtrdt(int qstn) { //配列の宣言 array<RadioButton^>^ arb = gcnew array<RadioButton^>(SZBH); for(int i=0; i<SZBH; i++) { arb[i] = dynamic_cast<RadioButton^>(this->Controls->Find("radioButton"+(qstn*SZBH-SZBH+1+i), true)[0]); } return this->chck(arb); } private: System::String^ chck(array<RadioButton^>^ arb) { for(int i=0; i<arb->Length; i++) { if(arb[i]->Checked == true) { return i + 1 + ","; } } return "×"; }

みんなの回答

回答No.2

System::String^ rtrdt(int qstn) {  array<RadioButton^>^ arb = gcnew array<RadioButton^>(SZBH);  for(int i=0; i<SZBH; i++)  {   arb[i] = dynamic_cast<RadioButton^>(    this->Controls->Find("radioButton"+(qstn*SZBH-SZBH+1+i),    true)[0]   );  }  return this->chck(arb); } この関数ですけど、渡すのは 問題番号(q) ですが、 問題番号が 2 だった場合、SZBH は 3 ですから "radioButton"+(qstn*SZBH-SZBH+1+i) ↓ "radioButton"+(2*3-3+1+i) ↓ "radioButton"+(4) 1回目のループでは i = 0 ↓ "radioButton4" というラジオボタンを探します。 ラジオボタンは3つですからありませんね。 見つからなかったときの処理がない為のエラーでしょう。 >return s->Remove(s->Length - 1); s->Length が 0 だった時のエラー処理がありません。 0 から 1 引くので -1 となり例外が発生します。 ラジオボタンのエラーでプログラムが停止するので こっちのエラーは見てないと思います。

回答No.1

まず改行しましょう。読めません。 button1_Click が「戻る」 button2_Click が「次に進む」 でいいでしょうか? flag、q、jump、endflag は、メンバ変数ですか? QSTNB は何でしょう? SZBH はラジオボタン数ですか? >arb[i] = dynamic_cast<RadioButton^>(this->Controls->Find("radioButton"+(qstn*SZBH-SZBH+1+i), true)[0]); >return s->Remove(s->Length - 1); この位置でインデックスが不正なためにエラーが出てると思います。 ソースを見た感じ「フォームアプリケーション」に手を出す前に C と C++ をマスターしてからのほうがいいと思いました。 あと変数名 q は無いですね。m_nQuestionNumber 位の名前がいいです。 (変数名は誰が見ても一瞬で理解できるようものを心がけましょう)

tierra31
質問者

補足

ご回答ありがとうございます。 >button1_Click が「戻る」  button2_Click が「次に進む」  でいいでしょうか? はい。その通りです。 >flag、q、jump、endflag は、メンバ変数ですか?  QSTNB は何でしょう?  SZBH はラジオボタン数ですか? メンバ変数です。 QSTNBは問題数でSZBHはラジオボタン数です。 >arb[i] = dynamic_cast<RadioButton^>(this->Controls->Find("radioButton"+(qstn*SZBH-SZBH+1+i), true)[0]); >return s->Remove(s->Length - 1); この位置でインデックスが不正なためにエラーが出てると思います。 申し訳ないのですが、どのようにすれば良いのか教えていただけますか?