I have to write a multiple choice program and the following code is as far as i've gotten. It's coming back with invalid answers and I'm not sure where i'm doing it wrong.


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,

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

void WrongSize (ofstream&, int, string);

int main()
{
	ifstream inData;
	ofstream outData;
	inData.open("exams.dat");
	outData.open("scores.dat");

	string key;
	string student;
	string answers;
	int keylength;

	inData >> key;
	keylength = key.length();

	while (!inData.eof())
{
	inData >> student;
	outData << student<< " ";
	inData >> answers;
	WrongSize (outData, keylength, answers);

if (answers.length() == keylength)
{
	int count;
	count = 1;
	while (count <= keylength)
{
	int grade;
	string answer;
	string letter;
	grade = 0;
	letter = key.substr(count, 1);
	answer = answers.substr(count, 1);
	if (answer < "a" || answer > "f")
{
	outData << "Invalid answers!" << endl;
}
	else if (letter == answer)
{
grade++;
count++;
}


}
}

}
return 0;
}


void sWrongSize (ofstream& outData,int keylength,string answers)
{
if (answers.length() < keylength)
{
outData << "Too few answers!" << endl;
}
else if (answers.length() > keylength )
{
outData << "Too many answers!" << endl;
}
else if (answers.length() == keylength)
{
return;
}
}

The loop starting on line 31 does more than what is necessary. Just use subscripts into the two strings

for( int count = 0; count < key.length(); count++)
{
   if( answers[count] == key[count] )
       grade++;
   else
       cout << "Answer # " << count+1 << " is wrong\n";
}

Edited 6 Years Ago by Ancient Dragon: n/a

I changed the code to:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

void WrongSize (ofstream&, int, string);

int main()
{
	ifstream inData;
	ofstream outData;
	inData.open("exams.dat");
	outData.open("scores.dat");

	string key;
	string student;
	string answers;
	int keylength;
	int grade;
	grade = 0;


	inData >> key;
	keylength = key.length();

	while (!inData.eof())
{
	inData >> student;
	outData << student<< " ";
	inData >> answers;
	WrongSize (outData, keylength, answers);

	}
for( int count = 0; count < key.length(); count++)
{
   if( answers[count] == key[count] )
	   grade++;
   else
	   outData << "Invalid answers" ;
}


return 0;
}


void WrongSize (ofstream& outData,int keylength,string answers)
{
if (answers.length() < keylength)
{
outData << "Too few answers" << endl;
}
else if (answers.length() > keylength )
{
outData << "Too many answers" << endl;
}
else if (answers.length() == keylength)
{
return;
}
}

The output definitely doesn't match..but it's a step closer..

The while loop is still wrong. It is not processing each line of the file, but only the last line. You need to put the loop starting on line 35 inside the while loop that starts on line 27.

Also, the use of eof() will not work. Here is what you should have while ( inData >> student >> answers ) With that you can delete lines 29 and 31.

I tried doing what you suggested and it came through as invalid answers and continued on a bunch of times over.

I replaced line #27 with

while (inData >> student >> answers )

and deleted lines 29 to 31, replacing with the loop that started on line 35.

Edited 6 Years Ago by micmagicfly: n/a

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

void WrongSize (ofstream&, int, string);

int main()
{
	ifstream inData;
	ofstream outData;
	inData.open("exams.dat");
	outData.open("scores.dat");

	string key;
	string student;
	string answers;
	int keylength;
	int grade;
	grade = 0;


	inData >> key;
	keylength = key.length();

	while (inData >> student >> answers )
{
	for( int count = 0; count < key.length(); count++)
{
   if( answers[count] == key[count] )
	   grade++;
   else
	   outData << "Invalid answers" ;
}

	WrongSize (outData, keylength, answers);

	}

return 0;
}


void WrongSize (ofstream& outData,int keylength,string answers)
{
if (answers.length() < keylength)
{
outData << "Too few answers!" << endl;
}
else if (answers.length() > keylength )
{
outData << "Too many answers!" << endl;
}
else if (answers.length() == keylength)
{
return;
}
}

Move line 37 up to just after line 30 so that it is called before the loop starts. The program will crash if answers string is not the same length as the key string. So WrongSize() function will have to be changed to return a value that indicates an error condition. Do not execute the loop on line 29 if WrongSize() returns an error value.

Edited 6 Years Ago by Ancient Dragon: n/a

So i'm probably going to sound like an idiot but I don't know how to do that. I thought that the if statements at the end of the program was the error messages....

I'm so lost..

bool WrongSize (ofstream& outData,int keylength,string answers)
{
    bool valid = false;
    if (answers.length() < keylength)
    {
         outData << "Too few answers!\n";
    }
    else if (answers.length() > keylength )
    {
        outData << "Too many answers!\n";
    }
    else
         valid = true;
    return valid;
}

int main()
{
  < snip >

  if( WrongSize (outData, keylength, answers) == true )
  {
	for( int count = 0; count < key.length(); count++)
       {
             if( answers[count] == key[count] )
                  grade++;
             else
                  outData << "Invalid answers" ;
}
  }
}

Edited 6 Years Ago by Ancient Dragon: n/a

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