True/False Test

I am writing a program to grade a True/False test. I have to read the students answers from an input file and output them, along with their percentage and letter grade, to an another file. The first line in the input file contains the answers to the test and the rest of the lines are the student's IDs followed by their answers. Here is the content of the input file inData.txt:

TFFTFFTTTTFFTFTFTFTT
ABC54301 TFFTFFTTTTFFTFTFTFTT
BBC54301 FFFFTFTTFTTTFFFFTTFT
CBC54301 FFTFTF TTTFTFTFTTFFT
DBC54301 TFTFTFTTFTTTTFFTFTFT
EBC54301 TFTFFFTTTTFTFTFFTTFT
FBC54301 FTTFTFTTTTTTFTFFTTFF
GBC54301 TFTFTFFFFTFTFTFFTTFT
HBC54301 TFTFTTFTFTFTFTFFTTFT
IBC54301 FFFFTTTTTFFTFFFFT FF
JBC54301 TTTFTFTTFTFTFTFFTTFT
KBC54301 FFTTTFFFTTFTFFTFTTFT
LBC54301 FFTFTFTTFTFTFFTFTTFF
MBC54301 TTTFTFTFTTTTFTFTFFTF
NBC54301 TFT TFFFFTFTTTFFTTFT
OBC54301 TFFFTFTTTTFTFTFFTTFT
PBC54301 TFTFTTTTTTFTFFF TTFT
QBC54301 TTFFTFFFTTFTFTFFTTFF
RBC54301 TTFFTFTTFTFTTFTFTTFF
SBC54301 FTF FTTTFTFTFTFFTTFT
TBC54301 FFTFTTTTFTTTTFFFTTFT

and here is 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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

double calculatePoints(char *answer, char *studentAnswer, double points);
void printResults(ofstream& out, string ID, char *studentAnswer, double totalPoints);

int main()
{
	ifstream input("inData.txt");
	ofstream output("outData.txt");
	double testPoints; //variable to store the test points
	string studentID; //variable to hold the student ID
	char *answerSheet=new char[21]; //array to store the answers
	char *testEntry=new char[21]; //array to store the student's answers

	input.get(answerSheet, 21);

	input >> studentID;
	while(input)
	{
		testPoints=0;
		input.get(testEntry,30);
		printResults(output, studentID, testEntry, calculatePoints(answerSheet,testEntry,testPoints));
		input >> studentID;
	}


	input.close();
	output.close();

    return 0;
}

double calculatePoints(char *answer, char *studentAnswer, double points)
{
	for(int index=0;index<20;index++)
	{
		if(studentAnswer[index]==answer[index])
			points+=2;
		else if(studentAnswer[index]!=answer[index] && studentAnswer[index]!=' ')
			points-=1;
	}

	return points;
}

void printResults(ofstream& out, string ID, char *studentAnswer, double totalPoints)
{
	out << setprecision(2) << fixed << showpoint;

	char grade;
	if(totalPoints>=36)
		grade='A';
	else if(totalPoints>=32)
		grade='B';
	else if(totalPoints>=28)
		grade='C';
	else if(totalPoints>=24)
		grade='D';
	else
		grade='F';

	out << ID << " "<< studentAnswer << " " << totalPoints/40*100 << "% " << grade << endl;
}


Basically line 67 with the expressions totalpoints/40*100 and grade is giving the wrong outputs. For example, the first student should receive 100% and a grade of A but the output says he has 5% and an F. I'm not sure what I did wrong. (Each correct answer recieves 2 points, a wrong answer gets minus one point, and a blank gets zero points. Theres 20 questions total so 40 points in all).
Last edited on
I spot some heap corruption:

1
2
3
4
5
6
	char *testEntry=new char[21]; // <- 21 chars
//...
	while(input)
	{
		testPoints=0;
		input.get(testEntry,30); // <- 30 chars 


You're trying to put 30 chars in a buffer that can only hold 21. This is corrupting the heap which could cause your program to do any number of strange things.

Fix that first and see if that solves the problem.
Yeah I tried input.get(testEntry,21); but got some weird ouput when i compiled that... also, shouldn't input.get(testEntry,30); read only 21 characters since theres a newline after that entry in the file?
also, shouldn't input.get(testEntry,30); read only 21 characters since theres a newline after that entry in the file?


Yes, if there is a newline it will stop at the newline. But the whole point of that 2nd parameter is to specify the size of the buffer so it doesn't overflow it. Buffer overflows are very bad. You should not be trying to read more than your buffer can hold.

And actually, the fact that you get different results with get(...,21) and get(...,30) shows that it is reading more than 21 characters, and you are corrupting the heap.

If your buffer only holds 21 characters, only read 21. If you need to read 30, then make your buffer big enough to hold 30.


I also noticed this:

1
2
3
4
5
6
7
8
	while(input)
	{
		testPoints=0;
		input.get(testEntry,30);
		printResults(output, studentID, testEntry, calculatePoints(answerSheet,testEntry,testPoints));
		input >> studentID;
	}


This is a little odd:

- You are printing the results before you even get the studentID.
- You are getting the answers before you get the studentID, even though the studentID is stored first in the file.

You probably should be geting the student ID first, then getting their answers, then printing the results.
O.K. I see what you're saying about the buffer so I fixed that by adding a char variable ch to read the newline and making the second paramater 21.
1
2
3
4
5
6
7
8
9
input >> studentID; //read the students ID
	while(input) 
	{
		testPoints=0;
		input.get(testEntry,21); //read the students answers
		input.get(ch); //get the newline
		printResults(output, studentID, testEntry, calculatePoints(answerSheet,testEntry,testPoints)); //now I can print everything
		input >> studentID; 
	}


-You are printing the results before you even get the studentID
Well before the loop I read the studentID. My grades still aren't functioning properly though. That last line in the function printResults isn't nice.
Finally, after a day of not knowing what went wrong, I found it and of course it is a simple mistake.
1
2
3
4
5
6
7
8
9
input >> studentID;
	while(input) 
	{
		input.get(ch); //this fixed the problem
		input.get(testEntry,21);
		input.get(ch); //this fixed the problem
		printResults(output, studentID, testEntry, calculatePoints(answerSheet,testEntry));
		input >> studentID;
	}

I was reading the blank character after the studentID in the array.
Topic archived. No new replies allowed.