this is the exact instructions:

"The program will grade a series of exams and then print a grade report for students in a course.

Input: An instructor has a class of students each of whom takes a multiple-choice exam with 10 questions. For each student in the class, there is one line in the input file. The line contains the answers that student gave for the exam. The input file named "grade_data.txt" will have the following format:

line 1: the key for the exam (e.g.)

bccbbadbca

lines 2-n:

a set of answers. You know you are done when you get to a line with no data.
Note: You will not know in advance how many exams you have to grade and you don't need to store the exam answers in your program.

Processing: The program is to read the input file and grade each exam and print out the score for that exam.

Output: Here is an example of how the output might appear. You will write the report to an output file named "grade_report.txt"

student 1 - 8
student 2 - 10
student 3 - 1
etc.

Final Report
------------

10 - 4
9 - 2
8 - 3
.
.
1 - 3
0 - 0

high score - 10

low score - 1

mean score - 6.25"


ive done a lot of it so far but i cant figure out how to do a few things. I cant figure out how to list how many people got question 1 right, question 2 right, etc. and im having trouble finding the highest/lowest/ and mean scores.

i didnt use any arrays on this project, and im not sure if it would be better to use an array for this kind of thing or if i can still make it work without any arrays.

this is the code i have so far:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

ifstream infile("grade_data.txt");
string grades, key;
string t1;
int temp;

int main()
{
    	if (!infile)
{
			 cout << "Error opening file\n\n";
			 system("pause");
}
        else
	         cout << "File Successfully Opened\n\n";
	         
	         
	         infile >> key;
	         
	         string a1 = key.substr(0,1);
             string a2 = key.substr(1,1);
             string a3 = key.substr(2,1);
             string a4 = key.substr(3,1);
             string a5 = key.substr(4,1);
             string a6 = key.substr(5,1);
             string a7 = key.substr(6,1);
             string a8 = key.substr(7,1);
             string a9 = key.substr(8,1);
             string a10 = key.substr(9,1);
            
	         
             cout<<endl;
             
             infile >> grades;
             while (!infile.eof())
{
             temp++;
             
             
             string b1 = grades.substr(0,1);
             string b2 = grades.substr(1,1);
             string b3 = grades.substr(2,1);
             string b4 = grades.substr(3,1);
             string b5 = grades.substr(4,1);
             string b6 = grades.substr(5,1);
             string b7 = grades.substr(6,1);
             string b8 = grades.substr(7,1);
             string b9 = grades.substr(8,1);
             string b10 = grades.substr(9,1);
             
             int results=0;
             
             if (a1==b1)
             results++;
             if (a2==b2)
             results++;
             if (a3==b3)
             results++;
             if (a4==b4)
             results++;
             if (a5==b5)
             results++;
             if (a6==b6)
             results++;
             if (a7==b7)
             results++;
             if (a8==b8)
             results++;
             if (a9==b9)
             results++;
             if (a10==b10)
             results++;
             

             int g;
             g=results*10;
             cout<<"Student "<<temp<<":    Made: "<<results<<"   Missed: "<<10-results<<"   Grade: "<<g<<"%\n";
             infile >> grades;             
                  
}
             
             
             

cout<<endl;
system("pause");
}

Too many string here. A keys string and a grades string are sufficient. No need for all the substrings. Just do this:

if(key[i] == grades[i]
{
    // right answer
}
else
{
    // wrong answer.
}

You'll need at least an array of integers to keep track of how many people scored 4 points, 5 points, 6 points, etc. I don't see a need for any other arrays. Your two strings are arrays anyway.

So something like this for variables:

const int NUM_QUESTIONS = 10;
string key;
string grades;
int scores[NUM_QUESTIONS + 1];
int results;

Get rid of a1 through a10 and b1 through b10 and all substr statements. They're unnecessary. Rename temp to something more descriptive and make sure to initialize it, or get rid of it.

You should also use a loop instead of all the repeated statements:

for(int i = 0; i < NUM_QUESTIONS; i++)
{
    if(key[i] == grades[i]
    {
        // right answer
    }
    else
    {
        // wrong answer.
    }
}

[EDIT]
Perhaps rename the "grades" variable to "answers" to be more descriptive?

Edited 6 Years Ago by VernonDozier: n/a

ok, heres my revised version. its working but its not finished.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

ifstream infile("grade_data.txt");
string answers, key;
string t1;
int num_grades;

const int NUM_QUESTIONS = 10;
int scores[NUM_QUESTIONS + 1];
int results=0;
int wrong=0;


int main()
{
    	if (!infile)
{
			 cout << "Error opening file\n\n";
			 system("pause");
}
        else
	         cout << "File Successfully Opened\n\n";
	         
	         
	         infile >> key;
	         
	         cout<<"  KEY\n";
	         for (int i=0; i < key.length(); i++)
	         cout<<" | "<<key[i]<<" | \n";
	         
	         
             cout<<endl;
             
             infile >> answers;
             while (!infile.eof())
{
             num_grades++;
             
             for (int a=0; a < answers.length(); a++)
             cout<<" | "<<answers[a]<<" | \n";
              
             
             for(int b = 0; b < NUM_QUESTIONS; b++)
{
    if(key[b] == answers[b])
    {
        results++;
    }
    else
    {
        wrong++;
    }
    
    //cout << scores[NUM_QUESTIONS + 1] << "\n";   for visual purposes
}

            
             int percent;
             percent=results*10;
             cout<<"Student "<<num_grades<<":    Made: "<<results<<"   Missed: "<<wrong<<"   Grade: "<<percent<<"%\n";
             infile >> answers; 
             
             results=0;
             wrong=0;            
              
}
             
             
             

cout<<endl;
system("pause");
}

i still need to make a table showing how many people go question 1-10 right. and i need to sort the grades in highest/lowest and average.

im going to continue working on it now, but help is appreciated.

Have another look at this part of VernonDozier's post

const int NUM_QUESTIONS = 10;
string key;
string grades;
int scores[NUM_QUESTIONS + 1];
int results;

You'll want something similar to Line 4. You will then have to create some code to manipulate the array. Think of each element of the array as a counter. If someone scores a 5, you increment element 5; score of 8, increment 8; and so on.

Edited 6 Years Ago by Fbody: n/a

can you explain a little more about line 4?...

ive tried using a numbered subscript for scores but i cant get it working.

You don't HAVE to use an array to hold all the scores, as arrays are just groups of individual variables of like type stored in contiguous memory. However, it is certainly neater to use arrays. The grades are arranged by how many answers were done correctly out of the 10 questions. Therefore the range of the grades could be anywhere from zero to 10, or 11 possible grades. Since the grades are ints they could act as indexes to the related element in the array. So array[5] would be number of people who got 5 answers correct and array[7] would be how many people got 7 answers correct, etc. If you initialize all the elements in the grade array to zero, then you can increment the appropriate element by one each time you get done grading a single students answers.

When you are done reading the file you can do the statistical analysis on the grade array. The highest and lowest grades are the index values of the highest and lowest non-zero elements of the grade array. The total number of test is the sum total of all the elements in the array. The average, well, you should be able to figure out the rest of it by yourself.

The table of student scores should be written to file when that students answers have been graded since you can't pull an individual students results out of the array.

Edited 6 Years Ago by Lerner: n/a

your talking about using scores right? i cant get it working, its always 0

Yeah, you use scores as the array to hold the grades. But, I don't see where you initialize the elements of scores to zero in the code posted.

In the code posted you could use the variable called results as the index to the element of scores you want to increment after grading the student answers.

From your earlier post:

Suppose you have 6 students. They have the following scores:

5, 7, 4, 5, 8, 5

By the time you've scored all the tests, your scores[] array should contain these values.

scores[0] = 0
scores[1] = 0
scores[2] = 0
scores[3] = 0
scores[4] = 1
scores[5] = 3
scores[6] = 0
scores[7] = 1
scores[8] = 1
scores[9] = 0
scores[10] = 0

Note that if you add the scores[] array, the sum is 6, which is exactly the number of students, and which is the exact number of times that you go through the big while loop.

That means that you must:

  1. Initialize all elements of scores[] to 0 BEFORE the while loop.
  2. Increment(i.e. add 1) to one of the elements of scores[] each time you go through the while loop.

Now, which element of scores[] should you increment? Well, say a student scored 4. What does scores[4] represent? The number students who scored exactly 4.

So there would be a line in there like this:

scores[4]++;

But actually not bcause the 4 is not hard-coded but instead is a variable. So this:

scores[someVariableName]++;

Now go through your code below and decide what the real variable is and replace someVariableName with the real variable and stick it at the bottom of the while loop.

And again, initialize everything to 0 BEFORE the while loop. Here's your code, formatted.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

ifstream infile("grade_data.txt");
string answers, key;
string t1;
int num_grades;

const int NUM_QUESTIONS = 10;
int scores[NUM_QUESTIONS + 1];
int results=0;
int wrong=0;


int main()
{
	if (!infile)
	{
		cout << "Error opening file\n\n";
		system("pause");
	}
	else
		cout << "File Successfully Opened\n\n";


	infile >> key;

	cout<<"  KEY\n";
	for (int i=0; i < key.length(); i++)
		cout<<" | "<<key[i]<<" | \n";


	cout<<endl;

	infile >> answers;
	while (!infile.eof())
	{
		num_grades++;

		for (int a=0; a < answers.length(); a++)
			cout<<" | "<<answers[a]<<" | \n";


		for(int b = 0; b < NUM_QUESTIONS; b++)
		{
			if(key[b] == answers[b])
			{
				results++;
			}
			else
			{
				wrong++;
			}

			//cout << scores[NUM_QUESTIONS + 1] << "\n";   for visual purposes
		}


		int percent;
		percent=results*10;
		cout<<"Student "<<num_grades<<":    Made: "<<results<<"   Missed: "<<wrong<<"   Grade: "<<percent<<"%\n";
		infile >> answers; 

		results=0;
		wrong=0;            

	}




	cout<<endl;
	system("pause");
}

Edited 6 Years Ago by VernonDozier: n/a

scores[0] = 0
scores[1] = 0
scores[2] = 0
scores[3] = 0
scores[4] = 1
scores[5] = 3
scores[6] = 0
scores[7] = 1
scores[8] = 1
scores[9] = 0
scores[10] = 0

@VernonDozier thats what im trying to get but i dont see where i can enter that to make it work.

this is the code i have now:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

ifstream infile("grade_data.txt");
string answers, key;
int num_grades;

const int NUM_QUESTIONS = 10;
double scores[NUM_QUESTIONS + 1];
double results=0.00;
int wrong=0;
double total=0.00;
double average=0.00;
double percent=0.00;
double temp=0.00;
int b;

int main()
{
    	if (!infile)
{
			 cout << "Error opening file\n\n";
			 system("pause");
}
        else
	         cout << "File Successfully Opened\n\n";
	         
	         
	         infile >> key;
	         
	         cout<<"  KEY\n";
	         for (int i=0; i < key.length(); i++)
	         cout<<" | "<<key[i]<<" | \n";
	         
	         
             cout<<endl;
             
             infile >> answers;
             while (!infile.eof())
{
             num_grades++;
             
             for (int a=0; a < answers.length(); a++)
             cout<<" | "<<answers[a]<<" | \n";
              
             
             for(b = 0; b < NUM_QUESTIONS; b++)
{
    
    if(key[b] == answers[b])
{
        results++;
        cout<<"CORRECT ANSWERS: "<<fixed<<setprecision(0)<<b+1<<"\n";  //which questions they are getting right.
}
    else
        wrong++;
     
    //cout << scores[NUM_QUESTIONS + 1] << "\n";
    
    
}
             
             percent=results*10;
             cout<<"Student "<<num_grades<<":    Made: "<<fixed<<setprecision(0)<<results<<"   Missed: "<<wrong<<"   Grade: "<<percent<<"%\n";
             
             for (int c=0; c<1;c++)
             total+=results;
             average=(total/num_grades);
             
             infile >> answers; 
             
             results=0;
             wrong=0;            
              
}
            
             cout<<"\n\nThe average of "<<num_grades<<" tests is: "<<fixed<<setprecision(2)<<average<<endl; 

cout<<"\n\n";
system("pause");
}

thanks for being patient and helping me, i dont normally have this much trouble :/

First, download an IDE like Net Beans or Visual Studio Express. Both are free. Both have debuggers and both have auto-formatters. In Visual Studio Express, highlight all the code, then select Edit->Advanced->Format Selection, then Edit->Advanced->Untabify Selected Lines. Then post on the forum. It will look WAY better. See below. Voila'!

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

ifstream infile("grade_data.txt");
string answers, key;
int num_grades;

const int NUM_QUESTIONS = 10;
double scores[NUM_QUESTIONS + 1];
double results=0.00;
int wrong=0;
double total=0.00;
double average=0.00;
double percent=0.00;
double temp=0.00;
int b;

int main()
{
    if (!infile)
    {
        cout << "Error opening file\n\n";
        system("pause");
    }
    else
        cout << "File Successfully Opened\n\n";


    infile >> key;

    cout<<"  KEY\n";
    for (int i=0; i < key.length(); i++)
        cout<<" | "<<key[i]<<" | \n";


    cout<<endl;

    infile >> answers;
    while (!infile.eof())
    {
        num_grades++;

        for (int a=0; a < answers.length(); a++)
            cout<<" | "<<answers[a]<<" | \n";


        for(b = 0; b < NUM_QUESTIONS; b++)
        {

            if(key[b] == answers[b])
            {
                results++;
                cout<<"CORRECT ANSWERS: "<<fixed<<setprecision(0)<<b+1<<"\n";  //which questions they are getting right.
            }
            else
                wrong++;

            //cout << scores[NUM_QUESTIONS + 1] << "\n";


        }

        percent=results*10;
        cout<<"Student "<<num_grades<<":    Made: "<<fixed<<setprecision(0)<<results<<"   Missed: "<<wrong<<"   Grade: "<<percent<<"%\n";

        for (int c=0; c<1;c++)
            total+=results;
        average=(total/num_grades);

        infile >> answers; 

        results=0;
        wrong=0;            

    }

    cout<<"\n\nThe average of "<<num_grades<<" tests is: "<<fixed<<setprecision(2)<<average<<endl; 

    cout<<"\n\n";
    system("pause");
}

Now look at line 13. What, in words, does the variable "results" represent? Put a comment with those words next to line 13.

Now look at line 14. What does "wrong" represent? Note that "results" is a double and "wrong" is an int. Look at line 67. Notice that you set the precision to 0. Note that you use the ++ operator on "results". Can "results" ever be a non-integer? If not, for consistency, make it an integer. And rename it to "right" to be more descriptive. You have a "wrong" variable. It makes sense to have a "right" variable.

Now re-read my last post. You are looking for a variable to use as the index.

scores[someVariableName]++;

Recall that if a student scored 4, then scores[4] needs to be incremented. What variable holds 4 when a student answered 4 answers correctly? (hint : go through the variable names and find a synonym for "correct").

Oh, what the heck. I'm sure you've figured it out by now:

scores[right]++;

Proper variable naming and proper variable typing are crucial in order to understand program flow. They just make it so much easier. I tend to go overboard and people make fun of me, but hey, who can't understand what this line does. Go through all your variables and make sure they:

  1. Have a good name.
  2. Have the proper type.
  3. Are initialized correctly and in the right place.

scores[] is uninitialized. It needs to be initialized to 0.

scores[numberOfQuestionsThisParticularStudentAnsweredCorrectly]++;

That's overkill, but you get the point regarding naming. Name them like that and you'll never ever be confused about what variable to use again.

Hopefully that gets you pointed in the right direction. I'm offline for the next several days, so I can't help any more, but there are lots of good helpers on this forum. Sometimes, though, if you get no answers, it's because when threads get long, people who haven't replied yet ignore them, so it can help to close the old thread and start a new one with whatever the current issue is. Good luck!

This article has been dead for over six months. Start a new discussion instead.