/* ------------------------------------------------------------------------ // This program reads a set of quiz questions from a file and presents // them to a user in random order. The shuffle algorithm does random // selection without replacement. // ------------------------------------------------------------------------ */ #include "tools.h" /* include commands and user defined utilities */ /* ---- Questions and answers --------------------------------------------- */ #define MAXQ 20 /* Maximum number of questions in the quiz. */ typedef struct { short number; char name[16]; char symbol[4]; } question_t; int get_quiz( int n, question_t qu[] ); int do_quiz( int k, question_t quiz[] ); void main( void ) { question_t quiz[MAXQ]; /* Array of questions and answers. */ int nq; /* Number of questions in the quiz. */ int right; /* Number of correct answers. */ banner(); printf( "\n Chemical Element Quiz\n" ); nq = get_quiz( MAXQ, quiz ); /* Read nq quiz questions from a file. */ printf( "\n This quiz has %i questions.\n", nq ); printf( " When you see an element name, enter its symbol and number.\n" ); right = do_quiz( nq, quiz ); printf( "\n You gave %i correct answers on %i questions.\n", right, nq ); bye(); } /* ----------------------------------------------------------------------------- */ int get_quiz( int n, question_t qu[] ) { char filename[256]; /* Name of input file holding questions. */ stream fin; /* Input stream for questions. */ int items; /* For the code returned by fscanf(). */ int k; /* Number of questions in the quiz. */ printf( "\n What quiz file do you want to use? " ); scanf ( "%255s", filename ); fin = fopen ( filename, "r" ); if (fin == NULL) fatal ( " Error: cannot open file %s", filename ); for (k = 0; k < n; ) { items = fscanf( fin, "%hi%15s%3s", &qu[k].number, qu[k].name, qu[k].symbol ); if (items == 3) ++k; /* all is well -- count the item. */ else if (feof( fin )) break; else { say( " Bad data while reading slot %i: ", n ); clean_and_log( fin, stderr ); } } return k; } /* ------------------------------------------------------------------------------- */ int do_quiz( int nq, question_t quiz[] ) { bool ask( question_t q ); /* Prototype for subfunction. */ int many = nq; /* Number of questions not yet asked. */ int score = 0; /* Number of correct answers so far. */ int k; /* Subscript of selected question. */ srand( time( NULL ) ); /* initialize random number generator. */ while (many > 0) { k = rand() % many; /* Choose subscript of next question. */ if( ask( quiz[k] ) ){ score++; printf( "\t YES ! Score one.\n" ); } else { printf( "\t Sorry, the answer is %s %hi \n", quiz[k].symbol, quiz[k].number ); } /* Now remove the question from further consideration. */ --many; /* Decrement the counter. */ quiz[k] = quiz[many]; /* Move last question into vacant slot. */ } return score; } /* ----------------------------------------------------------------------------------- */ bool ask( question_t qu ) { char symb[4]; /* User response for atomic symbol. */ short number; /* User response for atomic number. */ printf( "\n Element: %s\n", qu.name ); printf( "\t symbol ? "); scanf( "%3s", symb ); printf( "\t atomic number ? "); scanf( "%hi", &number ); return strequal( symb, qu.symbol ) && number == qu.number; }