#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 quesmaketions 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) { const char* inputFileName = "examdat.txt"; FILE* examfp = fopen(inputFileName, "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 = 0; // the total of exams completed fscan_key(examfp, &key); // Read the key from the data file /* load and grade exams */ while(!feof(examfp) && fpeek(examfp) != '\n') { totalExams++; exams = realloc(exams, sizeof(struct t_exam) * totalExams); // Reasize the array fscan_exam(examfp, &exams[totalExams - 1], key.questions); // load exam grade_exam(&exams[totalExams - 1], &key); // grade exam } free_exams(exams, totalExams); // house keeping! fclose(examfp); printf("foo\n"); 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 it to the stream return c;}