Multiple Choice Test Program

Having some problems with this program. This is the problem:

You’ve been asked to write a program to grade a multiple choice exam. The exam has 20 questions, each answered with a little in the range of ‘a’ through ‘f’. The data are stored on a file(exams.dat) where the first line is the key consisting of a string of 20 characters. The remaining lines on the files are exam answers, and consist of a student ID number, a space, and a string of 20 characters. The program should read the key, then read each exam and output the ID number and score to file scores.dat. Erroneous input should result in an error message. For example, given the data:

abcdefabcdefabcdefab
1234567 abcdefabcdefabcdefab
9876543 abddefbbbdefcbcdefac
5554446 abcdefabcdefabcdef
4445556 abcdefabcdefabcdefabcd
3332221 abcdefghijklmnopqrst

The program should output on scores.dat:

1234567 20
9876543 15
5554446 Too few answers
4445556 Too many answers
3332221 Invalid answers

Use functional decomposition to solve the problem and code the solution using functions as appropriate. Be sure to use proper formatting and appropriate comments in your code. The output should be neatly formatted, and the error messages should be informative.

Use at least two functions (properly documented with a header and pre/post conditions) in addition to main(): one function to get the id/answers of one student, and one to compute and output a student’s results. DO NOT use global variables to avoid passing parameters to the functions. When passing an ifstream or ofstream variable, pass it by reference. You do not need to check the answer key in any way (i.e, assume it is always correctly entered.) The student answers, however, need to be checked as per the text instructions. The format of the input file will be as described in the text. It helps to know something about string arrays so ask about them in class. Be sure to both document your functions pre/post conditions and to pass parameters appropriately.

and i have this as my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Date Written:  09/November/2013
// I have read and understand the lab submittal policy document.
//♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
using namespace std;

	// Prototypes

void ID_ANSWERS (ifstream&, ofstream&, string, string);
void TEST_RESULTS (ofstream&, int, string, string);

int main()
{
	// Definitions
	string Key,
		ID,
		Answers;
	int KeyLength;
	ifstream infile;
	ofstream outfile;
	char exit_char;

	// File Test
	infile.open("exams.dat");					
	if (!infile)			// Checks to varify if the input file is valid
	{                                               
	    cout << endl << "       *** Error: Can not open the input file ***" 
        << endl << endl << endl;       
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;                                 
	}

	outfile.open("scores.dat");
	if (!outfile)			// Checks to varify if the output file is valid
	{
		cout << endl << "       *** Error: Can not find the output file ***" 
        << endl << endl << endl;       
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;  
	}

	// Program
	cout << "Grading Program" << endl << endl << endl;			// Title
	infile >> Key;
	KeyLength = Key.length();
	cout << Key;
	while(infile >> ID >> Answers)
	{
		ID_ANSWERS(infile, outfile, ID, Answers);
		TEST_RESULTS (outfile, KeyLength, Key, Answers);
	}

	// Exit
	cout  << endl << endl << endl;
	cout << "Press any key then enter to exit ";
	cin >> exit_char;
	return 0;
}

	// Functions

void ID_ANSWERS (ifstream& infile, ofstream& outfile, string ID, string Answers)
	// Pre-
	// Post-

{
	infile >> ID >> Answers;
	outfile << ID << "  ";
}

void TEST_RESULTS (ofstream& outfile, int KeyLength, string Key, string Answers)
	// Pre-
	// Post-
{
	int grade = 0;
	if (Answers.length() < KeyLength)
	{
		outfile << "Too few answers";
	}
	else if (Answers.length() > KeyLength )
	{
		outfile << "Too many answers";
	}	
	else
	{
	bool check=false;

	for (int count = 0; count < Key.length(); count++)
	{
		if( Answers[count] == Key[count] )
		grade++;
		else if (Answers[count] != 'a' && Answers[count] != 'b' && Answers[count] != 'c' && Answers[count] != 'd' && Answers[count] != 'e' && Answers[count] != 'f')
		check=true;
	}
 
	if (check==true)
	{
		outfile << "Invalid Answer";
	}
	else
	{
		outfile << grade;
	}
	outfile << endl;
	}
	outfile << endl;
}


the output i keep getting looks like this:
9876543 20

4445556 Too few answers
3332221 Invalid Answer

Can anyone help me out or show me what i am doing wrong? Thanks
HELP PLEASE!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// date Written:  09/November/2013
// I have read and understand the lab submittal policy document.
//♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎


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

	// Prototypes

void ID_ANSWERS (ifstream&, ofstream&, string&, string&);
void TEST_RESULTS (ofstream&, int, string, string, string);

int main()
{
	// Definitions
	string Key,
		ID,
		Answers;
	int KeyLength;
	ifstream infile;
	ofstream outfile;
	char exit_char;

	// File Test
	infile.open("exams.dat");
	if (!infile)			// Checks to varify if the input file is valid
	{
	    cout << endl << "       *** Error: Can not open the input file ***"
        << endl << endl << endl;
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;
	}

	outfile.open("scores.dat");
	if (!outfile)			// Checks to varify if the output file is valid
	{
		cout << endl << "       *** Error: Can not find the output file ***"
        << endl << endl << endl;
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;
	}
	// Program
	cout << "Grading Program" << endl << endl << endl;			// Title
	getline(infile, Key);
	KeyLength = Key.length();
	cout << Key;

    ID_ANSWERS(infile, outfile, ID, Answers);
	while(!infile.fail())
	{
		TEST_RESULTS (outfile, KeyLength, Key, Answers, ID);
        ID_ANSWERS(infile, outfile, ID, Answers);
	}

	// Exit
	cout  << endl << endl << endl;
	cout << "Press any key then enter to exit ";
	cin >> exit_char;
	return 0;
}

	// Functions

void ID_ANSWERS (ifstream& infile, ofstream& outfile, string &ID, string &Answers)
	// Pre-
	// Post-

{

	getline(infile, ID, ' ');
	getline(infile, Answers);
}

void TEST_RESULTS (ofstream& outfile, int KeyLength, string Key, string Answers, string ID)
	// Pre-
	// Post-
{
	int grade = 0;
	outfile << ID << ' ';
	if (Answers.length() < KeyLength)
	{
		outfile << "Too few answers";
	}
	else if (Answers.length() > KeyLength )
	{
		outfile << "Too many answers";
	}
	else
	{
	bool check=false;

	for (int count = 0; count < Key.length(); count++)
	{
		if( Answers[count] == Key[count] )
		grade++;
		else if (Answers[count] != 'a' && Answers[count] != 'b' && Answers[count] != 'c' && Answers[count] != 'd' && Answers[count] != 'e' && Answers[count] != 'f')
		check=true;
	}

	if (check==true)
	{
		outfile << "Invalid Answer";
	}
	else
	{
		outfile << grade;
	}

    }
    outfile << endl;
}
Last edited on
i tried some of the changes that you added in but now im getting noresults at all in the outfile :( i think it might have to do with the last function but i cannot find where the problem is at
i still cant find out why it isnt working :( can someone please take a look and tell me why my last function is not printing anything to the outfile?
HEY! GOOD NEWS! i finnaly got it to print out the correct statments! the only problem is that now it is reading the last one through twice? any thoughts on how to fix that?
I'm going to talk about your original code (in your first post) below, since that's the one I just tried to compile and run.

In this loop:
55
56
57
58
59
while(infile >> ID >> Answers)
{
	ID_ANSWERS(infile, outfile, ID, Answers);
	TEST_RESULTS (outfile, KeyLength, Key, Answers);
}

In your loop, you grab the student's ID and their answers, but then in ID_ANSWERS, you do it again, which means you essentially throw away the next student's answers.
Note that since you don't pass ID and Answers by reference to your ID_ANSWERS function, your original ID and Answers that you declared in main remain unchanged, so you end up outputting the next student's ID (in ID_ANSWERS) but checking against the current student's answers (in main).
(That's why your output is one student "off".)

In fact, when I comment out line 75, everything runs correctly, except the line spacing is a bit weird (but that can be fixed by commenting out line 112).

EDIT: Hey, it looks like you fixed your original problem before I finished typing...
Last edited on
Thank you for your input anyways! it helps a lot to learn what my mistake was
i changed my loop to this:

while(!infile.fail())
{
ID_ANSWERS(infile, outfile, ID, Answers);
TEST_RESULTS (outfile, KeyLength, Key, Answers, ID);
}

but i am still getting (in my outfile) the last ID and Answer running twice do you know why that could be?
I'm not sure (I don't know exactly what you have so far), but if you just take the code you posted in your first post and make the changes I mentioned, then it works fine for me (and the last one doesn't run twice).
here is what i have so far and it is working perfectly ..... other than the fact that i get this as the answer:

1234567 20
9876543 15
5554446 Too few answers
4445556 Too many answers
3332221 Invalid Answer
3332221 Invalid Answer

.......... Why is the last students Answers running through twice?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎
// Lab 7 / Grading Program
// date Written:  09/November/2013
// I have read and understand the lab submittal policy document.
//♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎♎

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
using namespace std;

	// Prototypes
	void ID_ANSWERS (ifstream&, ofstream&, string&, string&);
	void TEST_RESULTS (ofstream&, int, string, string, string);

int main()
{
	// Definitions
	string Key,				// This is the answer key to the test
		ID,					// This is the students ID
		Answers;			// These are the students answers to the test
	int KeyLength;			// This is the length of the key
	ifstream infile;
	ofstream outfile;
	char exit_char;

	// File Test
	infile.open("exams.dat");
	if (!infile)			// Checks to varify if the input file is valid
	{
	    cout << endl << "       *** Error: Can not open the input file ***"
        << endl << endl << endl;
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;
	}

	outfile.open("scores.dat");
	if (!outfile)			// Checks to varify if the output file is valid
	{
		cout << endl << "       *** Error: Can not find the output file ***"
        << endl << endl << endl;
	    cout <<  "Enter any key to end execution of this program . . .  ";
	    cin >> exit_char;
	    return 1;
	}
	
	// Program
	cout << "Grading Program" << endl << endl << endl;			// Title
	getline(infile, Key);										// This grabs the key from the source file
	KeyLength = Key.length();									// This changes the key into an int for how long it is
	cout << "The Key that you have entered is: " << endl;
	cout << Key;
	outfile << "The Key that you have entered is: " << endl;
	outfile << Key << endl << endl << endl;

	while(!infile.fail())
	{
		ID_ANSWERS(infile, outfile, ID, Answers);
		TEST_RESULTS (outfile, KeyLength, Key, Answers, ID);
	}

	// Exit
	cout  << endl << endl << endl;
	cout << "Press any key then enter to exit ";
	cin >> exit_char;
	return 0;
}

	// Functions
void ID_ANSWERS (ifstream& infile, ofstream& outfile, string &ID, string &Answers)
{	// Pre-
	// Post-

	infile >> ID >> Answers;
}

void TEST_RESULTS (ofstream& outfile, int KeyLength, string Key, string Answers, string ID)
{	// Pre-
	// Post-
	
	int grade = 0;
	outfile << ID << ' ';
	if (Answers.length() < KeyLength)
	{
		outfile << "Too few answers";
	}
	else if (Answers.length() > KeyLength )
	{
		outfile << "Too many answers";
	}
	else
	{
	bool check=false;

	for (int count = 0; count < Key.length(); count++)
	{
		if( Answers[count] == Key[count] )
		grade++;
		else if (Answers[count] != 'a' && Answers[count] != 'b' && Answers[count] != 'c' && Answers[count] != 'd' && Answers[count] != 'e' && Answers[count] != 'f')
		check=true;
	}

	if (check==true)
	{
		outfile << "Invalid Answer";
	}
	else
	{
		outfile << grade;
	}

    }
    outfile << endl;
}
void ID_ANSWERS (ifstream& infile, ofstream& outfile, string ID, string Answers)
// Pre-
// Post-

{
infile >> ID >> Answers;
outfile << ID << " ";
}

you just need to Note //infile >> ID >> Answers in the function ID_ANSWERS,because you while loop has the same satement .That make you cannot read the file completely.
I would have to see the updated code
Last edited on
My guess is that after the last student, your while(!infile.fail()) check runs and it passes, since you haven't "failed" to get an input yet.
Then ID_ANSWERS runs and the input fails, since there's nothing left to get input from. But you're already inside the loop body, so TEST_RESULTS runs anyways with the ID and answers of the last student (which remained unchanged since the input failed in ID_ANSWERS). Then it loops back around and your while(!infile.fail()) check sees that the last input fails, so the loop ends and the rest of your program finishes.
your while loop is wrong look at how it is in my original post that is how it should be set up.

1
2
3
4
5
6
   ID_ANSWERS(infile, outfile, ID, Answers);
	while(!infile.fail())
	{
		TEST_RESULTS (outfile, KeyLength, Key, Answers, ID);
        ID_ANSWERS(infile, outfile, ID, Answers);
	}


ID_ANSWERS(infile, outfile, ID, Answers);
needs to be called before
while(!infile.fail())
Last edited on
Thank you guys for all your help i have it running perfectly now!
Topic archived. No new replies allowed.