I have written a C program, two integers are randomly selected, the numbers are either added or subtracted to form an equation, and the player is required to solve the equation. This code is compiled in Xcode v12.2.



Program intro:


i. Each round consists of 10 questions that are not repeated. Each round is to be set anew and no questions are allowed to be repeated with the previous rounds.

ii. Only addition and subtraction within 100 is allowed, the sum or difference of the two numbers should not exceed the range of 0-100, no negative values are allowed.

iii. For each question, players have 3 chances to enter their answers. 10 points are awarded for the first correct attempt, 7 points for the second attempt, 5 points for the third attempt, and zero points if all 3 attempts failed. When an incorrect answer is entered, a prompting message should appear so that the player is reminded to retry the question. Output correct answer if all 3 attempts are used.

iv. The player's score is displayed at the end of the game.

Here are the two problems that I am facing:


1. If I input a number/word/symbols other than the digits 1, 2, or 3, the prompt 'invalid input' DID NOT appear to prompt the user to input the correct number.



This is the part of the code that is responsible for the output:

Code:
int main()
{
    int i1=1;
    char name[25];// ig;
    printf(" Enter your name: ");         // Prompting the user to enter his/her name
    scanf("%[^\n]%*c", name);
    printf("\n Welcome %s\n", name);
    printf("\n Press Enter key to continue.");
    char enter = 0, choice;
    while (enter != '\r' && enter != '\n') {
        enter = getchar();
    }
    printf("\n");
    while (i1 != 0)
    {
        int len= (int)strlen(name)+1;   //to calculate the length of the input string plus the ! mark
        int welcome_len=10;        //to calculate the length of the welcome word plus the blank spaces
        int s=76-len-welcome_len;  //to calculate the total no of stars to print
        int star = (s/2);          //to calculate the no of start to print each side.
        printf(" ");
        if(s%2==1)                 //to check if the string is of even length or odd
        {
            for(int i=0;i<star+1;i++)   //if odd add 1 extra star on left side
            {
                printf("*");
            }
        }
        else
        {
            for(int i=0;i<star;i++)
            {
                printf("*");
            }
        }
            
        printf(" Welcome %s! ",name);   //print the name
            
        for(int i=0;i<star;i++)         //print * on the right side
        {
            printf("*");
        }
        
        printf("\n");
        //printf(" ********************** Welcome %s! *********************\n", name);
        printf(" *                       Main Menu of Maths Quiz                            *\n");
        printf(" * 1.Enter Quiz                                                             *\n");
        printf(" * 2.Instructions                                                           *\n");
        printf(" * 3.Quit                                                                   *\n");
        printf(" ****************************************************************************\n");
        printf(" Please choose one from 1-3:\n");
        printf(" ");
        scanf("%d", &i1);
        switch (i1)
        {
            case 1:
                    printf("\n Enter Quiz:\n");
                    quiz(name);        // calling quiz function defined in file "maincode.c"
                    break;
            case 2:
                    printf("\n Instructions:\n\n");
                    display_instructions();            // calling display_instructions function defined in file "maincode.c" to display instructions of quiz
                    printf("\n Back to main menu? ");
                    printf(" Press 'Y' for Yes.\n");
                printf(" ");
                choiceY("Instructions");            //to validate user input
                    break;
            case 3:
                    printf(" Are you sure you want to quit this program?\n");        // Confirming if user really wants to quit
                    printf(" Press 'Y' for Yes or 'N' for No: ");
                    choice=choiceY("Quit");             //to validate user input
                    if(choice == 'y')
                    {
                        i1 = 0;
                        printf(" Quit.\n");
                    }
                    else
                        continue;
                    
                    break;
                    
            default:
                    printf("Invalid input! Please select from options 1, 2 or 3\n");
        }
    }
    return 0;
}
This is the faulty output:

Facing 2 problems in my C code: Prompt missing + Faulty scores output-screenshot-2020-12-11-10-27-43-pm-jpg

As you can see, after inputting the letter 'k', the prompt 'invalid input' did not appear (even though I have it in my code). In addition, I cannot enter the quiz even though I have pressed the 'Enter' key.


2. Faulty scores output.

For each round, the program should output the highest and lowest scores and the average score.


This is the part of my code responsible for outputting the scores (and part of the quiz questions):

Code:
void quiz(char name[])
{
    // function created to enclose quiz functionality apart from instructions
    int rounds = 0;
    int highest = 0;
    int lowest = INT_MAX;
    float allScore = 0;
    float avg = 0;

    int i, j, g = 0;
    //char x;
    struct struc test[MAX_TESTS];

    srand((unsigned)time(NULL));


    for (;;) {

                for (i = 0; i < MAX_TESTS; i++)              // generate all questions
                {
                        ctm_i(&test[i]);

                        for (j = 0; j < i; j++)

                                if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
                                        //if question is already present
                                        ctm_i(&test[i]);    //then re-generate
                }
                //int ig = getchar();
        char x;
        x = getchar();
        printf("\n Are you ready? Press Enter key to continue. ");
        fflush(stdin);
        while(x!='\n') { }
                       while ( getchar() != '\n') { }
                       //getchar();
      
        for (i = 1; i <= 5; i++) {
            printf(
                " *******************************************************************"
                "**"
                "***********\n");

            printf(
                " ..................................................................."
                ".."
                "...........\n");
        }

        // Take quiz
        for (i = 0; i < MAX_TESTS; i++)
            tcm_i(&test[i], i);

        printf(" End\n\n");

        bool done = false;
        bool unsure = true;
        bool showS = true;

        while (unsure) {
            unsure = false;
            puts("\n");
            if (showS) {
                                puts(" Enter 'S' to show results");
                        }
            puts(" Enter 'P' to play another round");
            //puts(" Enter 'Q' to quit");
            puts(" Enter 'R' to return to main menu");
            char choice;
            printf(" ");
            myread("%c", &choice);
            
            if (choice == 'r' || choice == 'R')
               {
                                done = true;}
            else if (choice == 'S' || choice == 's') {
                                showS = false;
                                // calculate total score for current round
                                g = 0;
                                for (i = 0; i < MAX_TESTS; i++) {
                                                g += test[i].grade; //add score of each question
                                        }
                                allScore += g;  //add current round's score to total
                                avg = allScore / rounds;        //average of all rounds
                                
                                if (g > highest)
                                {
                                        highest = g;
                                }
                                
                                if (g < lowest)
                                {
                                        lowest = g;
                                }
                                
                if (rounds == 1)
                {
                    printf(" Final score: %d/100\n", g); //display round score
                    printf(" ****** Player: %s ******\n", name);
                }
                else {
                    //puts("Whoops! Looks like highest/lowest have not been adjusted!");
                    printf(" Round %d score: %d/100\n", rounds, g); //display round score
                    printf(" Highest score: %d/100\n", highest);
                    printf(" Lowest score: %d/100\n", lowest);
                    printf(" Average score: %f\n", avg);
                    printf(" ****** Player: %s ******\n", name);
                }
                unsure = true;
                //getchar();
            }
            else if (choice == 'P' || choice == 'p') {
             g = 0;
                                for (i = 0; i < MAX_TESTS; i++) {
                                                g += test[i].grade; //add score of each question
                                        }
                                allScore += g;  //add current round's score to total
                                if (g > highest)
                                {
                                        highest = g;
                                }
                                
                                if (g < lowest)
                                {
                                        lowest = g;
                                }
                
            }
            else {
                puts(" Invalid input!");
                unsure = true;
            }
        }
        if (done)
            break;
    }
}
a. This is the scores output after playing 1 round:

Facing 2 problems in my C code: Prompt missing + Faulty scores output-screenshot-2020-12-11-10-36-58-pm-png

Why is 'Round 1' shown as 'Round 0'? And what does the 'inf' mean in the average score section? Please help me turn 'inf' into a numerical output.


b. After playing for 2 rounds and choosing to output the scores, the output shows this:

Facing 2 problems in my C code: Prompt missing + Faulty scores output-screenshot-2020-12-11-10-39-27-pm-png

'Round 2'
is still shown as 'Round 0' and the 'Average score' did not change to a numerical output.

Any help would be greatly appreciated.

This is the full code for further reference:
Code:
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define MAX_TESTS 10
#define MAXQUESTION 100

bool myread(const char* format, void* address)
{
    char buffer[1024];
    fgets(buffer, sizeof buffer, stdin);
    return sscanf(buffer, format, address) == 1;
}

struct struc {
    int a;

    int b;

    int c;

    int add;

    int grade;
};

struct struc ques_db[MAXQUESTION];//database to hold all the previous questions

int ques_db_count = 0;//count of question currently in the database

//function to traverse the question in database and
// see if the current question has already been asked
int find_in_db(struct struc *t)
{ int i;
for (i = 0; i < ques_db_count; i++)
{
// check to see if the question in database is same as
// the current generated one. It compares value of a, b
// add (i.e. result) if all of them are same then the
// question was same as the current one

if ( ques_db[i].a == t->a &&
ques_db[i].b == t->b &&
ques_db[i].add == t->add )
return -1;
}

return 0;
}

int add_in_db(struct struc *t)//function to add the currently generated question to database

{
//first check if the question is already there in the db
if (-1 == find_in_db(t))
return -1;
else
{ // if not there then add to the db for future reference
ques_db[ques_db_count++] = *t;
return 0;
}
}

int sj(int n)
{
    int t;

    t = rand() % n;

    return t;
}

void ctm_i(struct struc* t)
{
    do
    {
            t->a = sj(101);
            t->c = sj(4);
            if (t->c == 1)
            {
                t->b = sj(101 - (t->a));
                t->add = (t->a) + (t->b);
            }
        else
        {
            t->b = sj((t->a) + 1);
            t->add = (t->a) - (t->b);
        }
            t->grade = 0;
    }
    while(add_in_db(t) != 0); //process repeats if question is not added due to repetition
}


void print_positive_message(){
    char positive_words[8][50] = {
      "\n Bingo!",
      "\n Great job!",
      "\n Very good!",
      "\n Brilliant!",
      "\n That's correct!",
      "\n You got it!",
      "\n Bravo!",
      "\n Awesome!"
    };

   srand((unsigned) time(NULL));
   // Replace your print statement here
   printf("%s", positive_words[rand() % 8]);
}

void tcm_i(struct struc* t, int n)
{
    int ad;
    
    printf(
        " ***********************************************************************"
        "*********\n");

    printf(
        " ......................................................................."
        ".........\n");

    printf(" Question %d\n\n", n + 1);

    printf(" You have 3 attempts for this question\n\n");
        
    if (t->c == 1)
        printf(" %d+%d= ", t->a, t->b);
    else
        printf(" %d-%d= ", t->a, t->b);
        
    myread("%d", &ad);
    if (ad == t->add)

    {
        t->grade = 10;
        
        print_positive_message();

        printf(" You earned 10 marks\n\n");
    }

    else {
        printf("\n Incorrect, you have 2 attempts remaining\n\n");
        printf(" ");
        myread("%d", &ad);

        if (ad == t->add)

        {
            t->grade = 7;
            
            print_positive_message();

            printf(" You earned 7 marks\n\n");
        }

        else {
            printf("\n Incorrect, you have 1 attempt remaining\n\n");
            printf(" ");
            myread("%d", &ad);

            if (ad == t->add)

            {
                t->grade = 5;
                
                print_positive_message();

                printf(" You earned 5 marks\n\n");
            }

            else {
                t->grade = 0;

                printf("\n Failure, 0 mark\n\n");

                printf("\n The correct answer is %d\n\n", t->add);
            }
        }
    }

    printf(
        " ......................................................................."
        ".........\n");

    printf(
        " ***********************************************************************"
        "*********\n");
}

void display_instructions() {
    // function created only to display instructions of quiz
    printf(
        " ***********************************************************************"
        "************\n");

    printf(
        " ......................................................................."
        "............\n");

    printf(
        " ************************************* Welcome! ************************************\n");
   
    printf(" ......................This program is for students Grades 1-2......................\n");

    printf("\n Program description:\n");

    printf(
        " (1)10 questions are randomly generated, each question is worth 10 points.\n");
    printf(" (2)Only addition and subtraction within 100 is allowed.\n    The sum and the difference of the two numbers do not exceed the range of 0-100.\n    Negative numbers are not included.\n");
    printf(" (3)There are 3 attempts for each question.;\n");
    printf(" (4)For each question:\n        1. 10 points will be awarded for the first successful attempt.\n        2. 7 points for the second attempt.\n        3. 5 points for the third attempt.\n");
    printf(
        " (5)At the end of the program enter:\n        'P' to start a new game;\n        'S' to show the results;\n        'Q' to quit.\n\n");
    printf(
        " ......................................................................."
        ".........\n");
}

void quiz(char name[])
{
    // function created to enclose quiz functionality apart from instructions
    int rounds = 0;
    int highest = 0;
    int lowest = INT_MAX;
    float allScore = 0;
    float avg = 0;

    int i, j, g = 0;
    //char x;
    struct struc test[MAX_TESTS];

    srand((unsigned)time(NULL));


    for (;;) {

                for (i = 0; i < MAX_TESTS; i++)              // generate all questions
                {
                        ctm_i(&test[i]);

                        for (j = 0; j < i; j++)

                                if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
                                        //if question is already present
                                        ctm_i(&test[i]);    //then re-generate
                }
                //int ig = getchar();
        char x;
        x = getchar();
        printf("\n Are you ready? Press Enter key to continue. ");
        fflush(stdin);
        while(x!='\n') { }
                       while ( getchar() != '\n') { }
                       //getchar();
      
        for (i = 1; i <= 5; i++) {
            printf(
                " *******************************************************************"
                "**"
                "***********\n");

            printf(
                " ..................................................................."
                ".."
                "...........\n");
        }

        // Take quiz
        for (i = 0; i < MAX_TESTS; i++)
            tcm_i(&test[i], i);

        printf(" End\n\n");

        bool done = false;
        bool unsure = true;
        bool showS = true;

        while (unsure) {
            unsure = false;
            puts("\n");
            if (showS) {
                                puts(" Enter 'S' to show results");
                        }
            puts(" Enter 'P' to play another round");
            //puts(" Enter 'Q' to quit");
            puts(" Enter 'R' to return to main menu");
            char choice;
            printf(" ");
            myread("%c", &choice);
            
            if (choice == 'r' || choice == 'R')
               {
                                done = true;}
            else if (choice == 'S' || choice == 's') {
                                showS = false;
                                // calculate total score for current round
                                g = 0;
                                for (i = 0; i < MAX_TESTS; i++) {
                                                g += test[i].grade; //add score of each question
                                        }
                                allScore += g;  //add current round's score to total
                                avg = allScore / rounds;        //average of all rounds
                                
                                if (g > highest)
                                {
                                        highest = g;
                                }
                                
                                if (g < lowest)
                                {
                                        lowest = g;
                                }
                                
                if (rounds == 1)
                {
                    printf(" Final score: %d/100\n", g); //display round score
                    printf(" ****** Player: %s ******\n", name);
                }
                else {
                    //puts("Whoops! Looks like highest/lowest have not been adjusted!");
                    printf(" Round %d score: %d/100\n", rounds, g); //display round score
                    printf(" Highest score: %d/100\n", highest);
                    printf(" Lowest score: %d/100\n", lowest);
                    printf(" Average score: %f\n", avg);
                    printf(" ****** Player: %s ******\n", name);
                }
                unsure = true;
                //getchar();
            }
            else if (choice == 'P' || choice == 'p') {
             g = 0;
                                for (i = 0; i < MAX_TESTS; i++) {
                                                g += test[i].grade; //add score of each question
                                        }
                                allScore += g;  //add current round's score to total
                                if (g > highest)
                                {
                                        highest = g;
                                }
                                
                                if (g < lowest)
                                {
                                        lowest = g;
                                }
                
            }
            else {
                puts(" Invalid input!");
                unsure = true;
            }
        }
        if (done)
            break;
    }
}
     // importing maincode.c file to allow to call quiz() an display_instructions()

char choiceY(char option[30])
{
    char choice;
    scanf(" %c", &choice);                      //take user input
    if(choice == 'y' || choice == 'Y')
        return 'y';
        
    else
    {
        if (strcmp(option,"Quit")  == 0)                      //if the input is for quit check wheather entered No
        {
            if(choice == 'n' || choice == 'N')
            return 'n';
            printf(" Invalid input! Please enter 'Y' to Quit or 'N' to return to the main menu: ");
        
        }
        else
            printf("\n\tInvalid input! Please enter 'Y' to return to the main menu: ");
            
        choiceY(option);                        //if enter invalid input recursive call the choiceY function
    }
    return '0';
}

int main()
{
    int i1=1;
    char name[25];// ig;
    printf(" Enter your name: ");         // Prompting the user to enter his/her name
    scanf("%[^\n]%*c", name);
    printf("\n Welcome %s\n", name);
    printf("\n Press Enter key to continue.");
    char enter = 0, choice;
    while (enter != '\r' && enter != '\n') {
        enter = getchar();
    }
    printf("\n");
    while (i1 != 0)
    {
        int len= (int)strlen(name)+1;   //to calculate the length of the input string plus the ! mark
        int welcome_len=10;        //to calculate the length of the welcome word plus the blank spaces
        int s=76-len-welcome_len;  //to calculate the total no of stars to print
        int star = (s/2);          //to calculate the no of start to print each side.
        printf(" ");
        if(s%2==1)                 //to check if the string is of even length or odd
        {
            for(int i=0;i<star+1;i++)   //if odd add 1 extra star on left side
            {
                printf("*");
            }
        }
        else
        {
            for(int i=0;i<star;i++)
            {
                printf("*");
            }
        }
            
        printf(" Welcome %s! ",name);   //print the name
            
        for(int i=0;i<star;i++)         //print * on the right side
        {
            printf("*");
        }
        
        printf("\n");
        //printf(" ********************** Welcome %s! *********************\n", name);
        printf(" *                       Main Menu of Maths Quiz                            *\n");
        printf(" * 1.Enter Quiz                                                             *\n");
        printf(" * 2.Instructions                                                           *\n");
        printf(" * 3.Quit                                                                   *\n");
        printf(" ****************************************************************************\n");
        printf(" Please choose one from 1-3:\n");
        printf(" ");
        scanf("%d", &i1);
        switch (i1)
        {
            case 1:
                    printf("\n Enter Quiz:\n");
                    quiz(name);        // calling quiz function defined in file "maincode.c"
                    break;
            case 2:
                    printf("\n Instructions:\n\n");
                    display_instructions();            // calling display_instructions function defined in file "maincode.c" to display instructions of quiz
                    printf("\n Back to main menu? ");
                    printf(" Press 'Y' for Yes.\n");
                printf(" ");
                choiceY("Instructions");            //to validate user input
                    break;
            case 3:
                    printf(" Are you sure you want to quit this program?\n");        // Confirming if user really wants to quit
                    printf(" Press 'Y' for Yes or 'N' for No: ");
                    choice=choiceY("Quit");             //to validate user input
                    if(choice == 'y')
                    {
                        i1 = 0;
                        printf(" Quit.\n");
                    }
                    else
                        continue;
                    
                    break;
                    
            default:
                    printf("Invalid input! Please select from options 1, 2 or 3\n");
        }
    }
    return 0;
}