0

I am working on a project which involves creating two arrays and comparing the answers to determine a pass or fail state.

When I try to run my code I receive this error:

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in ITEC exam.exe
Additional information: Index was outside the bounds of the array.

my code is as follows

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ITEC_exam
{
    public partial class ITEC_exam : Form
    {
        public ITEC_exam()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string line;
            int cnt = 0;

            //List to hold question numbers of incorrect answers
            List<int> incorrect = new List<int>();

            //Array to store correct answers
            string[] correctAnswers = { };

            //Array to store answers
            string[] answers = { };

            //Read the files and store answers in arrays
            System.IO.StreamReader correctFile = new System.IO.StreamReader("C:\\Users\\a_day\\Desktop\\Baker_Austin_c#_final\\ITECexam\\ITEC exam\\correctAnswers.txt");
            System.IO.StreamReader answerFile = new System.IO.StreamReader("C:\\Users\\a_day\\Desktop\\Baker_Austin_c#_final\\ITECexam\\ITEC exam\\testResult.txt");

            if ((line = correctFile.ReadLine()) != null)
                correctAnswers = line.Split(' ');

            if ((line = answerFile.ReadLine()) != null)
                answers = line.Split(' ');

            //Compare answers and compute the score
            for (int i = 0; i < 21; i++)
            {
                if (String.Compare(correctAnswers[i], answers[i]) == 0)
                    cnt++;
                else
                    incorrect.Add(i + 1);
            }

            //Print Result
            if (cnt >= 15)
                Console.WriteLine("\n\n Result: PASS");
            else
                Console.WriteLine("\n\n Result: FAIL");

            //Printing score
            Console.WriteLine("\n Total number of Correct Answers: " + cnt);
            Console.WriteLine("\n Total number of Incorrect Answers: " + (20 - cnt));

            Console.Write("\n Question numbers of incorrect answers: ");
            //Printing incorrectly answered question numbers
            foreach (int qno in incorrect)
                Console.Write(" " + qno + " ");

            //Closing Files
            correctFile.Close();
            answerFile.Close();

            Console.WriteLine("\n\n Press any key to exit.");
            Console.ReadKey();
        }
    }
}
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Austin
  • 11
  • 1
  • 4
  • How many items do the `correctAnswers` and `answers` arrays contain? – Steve Dec 01 '16 at 05:17
  • 20 in each file – Austin Dec 01 '16 at 05:25
  • Possible duplicate of [What is an IndexOutOfRangeException and how do I fix it?](http://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-and-how-do-i-fix-it) – Steve Dec 01 '16 at 05:27
  • 1
    Your loops is trying to access 21 elements, not 20. `i` goes from 0 to 20, and that's 21 elements. You should always loop checking the amount of elements and not blindly. – Andrew Dec 01 '16 at 05:34

5 Answers5

2

Your for loop assume that there are 20 or more items in the both lists, if you don't have 20 items in any of the list correctAnswers[i], answers[i] will fail. validate before access by index.

I assume in answers you have some flag like NA which is not in the actual answer list for the unattempted questions/ unanswered questions

Don't put empty or space for unattempted questions/ unanswered questions it will then generate more items in the results array in the answer list after split by space.

Also if you have answers with multiple words then this approach will be fail. (since you are split by space)

if(correctAnswers.Length == answers.Length)
{
  for (int i = 0; i < correctAnswers.Length; i++)
  {
       if (String.Compare(correctAnswers[i], answers[i]) == 0)
           cnt++;
       else
           incorrect.Add(i + 1);
   }

}

Other Options: you can create Answer class and add few properties like Question ID, Answer, Marks etc.. Then you can create list of answers from this class and save entire list to a file and read back to a list from file using serialize and deserialize

check write list of objects to a file

Community
  • 1
  • 1
Damith
  • 62,401
  • 13
  • 102
  • 153
  • Actually it's assuming there are 21 elements (`i` goes from 0 to 20 inclusive). – Andrew Dec 01 '16 at 05:34
  • This is probably wrong, your skipping grading a test because they didn't amswer all the questions. In actuality you should either be using Math.Min(correctAnswers.Length, answers.Length), which would be the most correct but you should store it in a var before using it in the loop, or be checking both. I took the liberty of updating your answer for you – johnny 5 Dec 01 '16 at 05:36
  • What if correctAnswers = 20 but answers = 17? when i = 17, the condition `i < correctAnswers.Length` is true but `i < answers.Length` is false. Hence the incorrect/unattempted answers wont go in the `incorrect` list – Amey Kamat Dec 01 '16 at 05:47
  • @johnny5 please don't update answers as you wish. I put that validation in the top for reason. – Damith Dec 01 '16 at 05:54
  • @AmeyKamat saving answers and questions in file, separate by space is the issue here. but question is asking about exception. there may be skipped answers etc.. OP need to find a way to solve that with his approach but it is not the scope of the question – Damith Dec 01 '16 at 05:58
  • @Damith you could also solve the problem by omitting that code all together, that too would make your exception go away... but im sure you agree thats not a viable option, if you were to evaluate this as if you were acting in a real world situation, you would grade the test regardless of if they answered the questions. – johnny 5 Dec 01 '16 at 06:08
  • but then again your right, the OP should figure out a way to solve this considering this is clearly homework, and will never be used in a real world application what so ever – johnny 5 Dec 01 '16 at 06:09
0

You are iterating over array of size 20 and accessing the value at 20th index. Check your for loop. It should access index 0 to 19, not 0 to 20.

Ashish
  • 11
  • 6
0

Should not use "21" for count, answers may be empty or less than 21.

So use as following.

//Compare answers and compute the score
for (int i = 0; i < answers.Length && i < correctAnswers.Length; i++)
{
    if (String.Compare(correctAnswers[i], answers[i]) == 0)
        cnt++;
    else
        incorrect.Add(i + 1);
}
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
-1

you need to check the array as below to avoid exception.

    //Compare answers and compute the score
    for (int i = 0; i < correctAnswers.Count(); i++)
    {
        if (answers.Count() > i && String.Compare(correctAnswers[i], answers[i]) == 0))
            cnt++;
        else
            incorrect.Add(i + 1);
    }
Amey Kamat
  • 181
  • 2
  • 12
  • that resolved that exception I was running into, however now I am running into another issue as well at the end of my code where it is supposed to output to a console out put it shows a exception as well – Austin Dec 01 '16 at 05:37
  • @Austin can you tel the exact line where it breaks and what exception is it giving you? – Amey Kamat Dec 01 '16 at 05:40
  • I was able to fix it it had to do with the Console.ReadKey();, i changed it to Console.Read(); Currently the program runs with no errors or exceptions. That being said the console window does not appear at all with my program ; is there a way to get console to show in windows or will I need to put the output in a list box or something – Austin Dec 01 '16 at 05:45
  • @Austin if it is a console application, you should be seeing a console when you run your code. if it is a winform then you will need to output in the UI. Looking at the code snippet you provided above, it is clear you are using WinForm. You will have to use a ListBox in this case. – Amey Kamat Dec 01 '16 at 05:51
  • kk thanks! That helps a lot this is my first coding experience and I am still getting used to what I am and not able to do . – Austin Dec 01 '16 at 05:54
-1
for (int i = 0; i < 21; i++)
{
    if (i < correctAnswers.Length && i < answers.Length)
    {
        if (String.Compare(correctAnswers[i], answers[i]) == 0)
            cnt++;
        else
            incorrect.Add(i + 1);
    }
    else
        incorrect.Add(i + 1);
}

In for-loop first check two arrays has index of i then check your condition.

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Surya
  • 103
  • 1
  • 7
  • Warning: that code is the original failing one, not a solution. If you submit an answer, try to make it one. – Andrew Dec 01 '16 at 05:37
  • can you look into description.i tried to give the answer with explanation. – Surya Dec 01 '16 at 05:44