All pastes #754751 Raw Edit

Something

public text v1 · immutable
#754751 ·published 2007-10-30 06:06 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>

/* Represents a students test */
struct t_exam {
	int studentId; // the stuendent's unique id
	char* answers; // responses to questions
	int* correct; // questions that were right
	int* incorrect; // questions that were wrong;
	int grade; // (correct / questions) * 100
	int totalCorrect; // total questions correct
	int totalIncorrect; // total questions wrong
};

/* Represents the answers to an exam */
struct t_exam_key {
	int questions; // number of questins on exam
	char* answers; // the answers for the exam
};

/**
 * int fscanf_key(FILE* fp, struct t_exam_key* key):
 *   fscans the number of questions and their answers from
 * FILE at fp and stores in key.
 * returns 1 if success, returns 0 if failure
 */
int fscan_key(FILE* fp, struct t_exam_key* key);

/**
 * int fscan_exam(FILE* fp, struct t_exam* exam, int questions):
 *   fscans an exam entry from FILE at fp with arg3 questions.
 * returns 1 if success, returns 0 if failure 
 */
int fscan_exam(FILE* fp, struct t_exam* exam, int questions);

/**
 * int grade_exam(struct t_exam* exam, struct t_exam_key* key):
 *   grades exam arg1 using exam_key arg2 as answer key
 * returns 1 if success, returns 0 if failure 
 */
void grade_exam(struct t_exam* exam, struct t_exam_key* key);

/**
 * char fpeek(FILE  fp):
 * returns the next character to be read, but restores stream
 */
char fpeek(FILE* fp);

/**
 * void free_exams(struct t_exam* exams, int number); 
 * Iterates through an array of exams, freeing allocated memory 
 * therein and finally freeing the first element of the array.
 */
void free_exams(struct t_exam* exams, int number);

int main(int argc, char **argv) {
	FILE* examfp = fopen("examdat.txt", "r"); // the exam data
	struct t_exam_key key; // the grading key for the exam
	struct t_exam* exams = malloc(sizeof(struct t_exam)); // start to make room
	int totalExams; // the total of exams completed
	
	fscan_key(examfp, &key); // Read the key from the data file
	
	/* load the exams in the file into the array and then grade*/
	for(totalExams = 0; !feof(examfp) && fpeek(examfp) != '\n'; totalExams++) {
		exams = realloc(exams, sizeof(struct t_exam) * totalExams + 1); // Reasize the array
		fscan_exam(examfp, &exams[totalExams - 1], key.questions); // make
		grade_exam(&exams[totalExams - 1], &key);
	}
	
	free_exams(exams, totalExams);
	
	fclose(examfp);
	
	return 0;
}

int fscan_key(FILE* fp, struct t_exam_key* key) {
	if(!fscanf(fp, "%d", &key->questions)) { // scan the # of questions
		return 0; // fail if they aren't there
	}
	
	key->answers = malloc(key->questions); // make space for answers
	
	if (!fscanf(fp, " %s\n", key->answers)) { // store the answers
		return 0; // fail if you can't
	}
	
	return 1; // success!
}

void grade_exam(struct t_exam* exam, struct t_exam_key* key) {
	exam->totalCorrect = 0;
	exam->totalIncorrect= 0;
	exam->incorrect = malloc(sizeof(int) * key->questions);
	exam->correct = malloc(sizeof(int) * key->questions);
	
	int i;
	for (i = 0; i < key->questions; i++) {
		if (exam->answers[i] == key->answers[i]) {
			exam->totalCorrect++;
			exam->correct[i] = i;
		} else {
			exam->totalIncorrect++;
			exam->incorrect[i] = i;
		}
	}
	
	exam->grade = (exam->totalCorrect / ((float) key->questions)) * 100;  
}

int fscan_exam(FILE* fp, struct t_exam* exam, int questions) {
	exam->answers = malloc(questions);
	
	if (!fscanf(fp, "%d %s\n", &exam->studentId, exam->answers)) {
		free((void*)&exam->answers); // not needed anymore
		return 0;
	}
	
	return 1;
}

void free_exams(struct t_exam* exams, int number) {
	int i;
	for(i = 0; i < number; i++) {
		free((void*) exams[i].answers);
		free((void*) exams[i].correct);
		free((void*) exams[i].incorrect);
	}
	
	free((void*) &exams);
}

char fpeek(FILE* fp) {
	char c = fgetc(fp);
	ungetc(c, fp);
	return c;
}