Thread: Weird 'Enter' key glitches

  1. #1
    Registered User
    Join Date
    Nov 2020
    Posts
    12

    Weird 'Enter' key glitches

    C program. IDE used Xcode v12.2

    The problem I'm facing:

    I need to press the 'Enter' key twice after typing the letter 'P' if I want to output the next sentence. I'm pretty sure that previously I just needed to press the 'Enter' key once in order to do so. What's surprising is that typing the letters 'S' or 'R' will only require pressing the 'Enter' key once to get the desired results. What could have possibly gone wrong?

    Code:
    void quiz(char name[])
    {
        int rounds = 0;
        int highest = 0;
        int lowest = INT_MAX;
        float allScore = 0;
        int avg = 0;
    
        int i, j, g = 0;
        struct struc test[MAX_TESTS];
    
        srand((unsigned) time(NULL));
    
        for (;;)
        {
            rounds++;
            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
            }
            char x;
            x = getchar();
            printf("\n Are you ready? Press Enter key to continue. ");
            fflush(stdin);
            while (x != '\n') {}
            while (getchar() != '\n') {}
    
            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 'R' to return to main menu");
                char choice;
                printf(" ");
                myread("%c", &choice);
                if (choice == 'r' || choice == 'R')
                {
                    done = true;
                }
                else
                {
    
                    ///////////////////////// Changes    /////////////
    
                    g = 0;
                    // calculate total score for current round
                    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 (choice == 'S' || choice == 's')
                    {
                        showS = false;
                        if (rounds == 1)
                        {
                            printf(" Final score: %d/100\n", g);    //display round score
                            printf(" ******Player: %s ******\n", name);
                        }
                        else
                        {
                            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: %d/100\n", avg);
                            printf(" ******Player: %s ******\n", name);
                        }
                        unsure = true;
                    }
                    else if (choice == 'P' || choice == 'p')
                    {
                             /// nothing to be done here
                        //we will display next test
                    }
                    else
                    {
                        puts(" Invalid input!");
                        unsure = true;
                    }
    
                    ////////////////////////////////////
    
                }
            }
            if (done)
                break;
        }
    }
    Weird 'Enter' key glitches-screenshot-2020-12-15-7-40-41-pm-png

    Any help would be greatly appreciated.

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    You should a full program with the main() function so we can compile and test the program.

    fflusf() is for output files only, fflush(stdin) should NEVER be used!

    Code:
    srand((unsigned) time(NULL));
    This should be called once in the main() function, not every time quiz() is called.

    Where do you actually call rand()?

    Where is and what is myread()?

  3. #3
    Registered User
    Join Date
    Nov 2020
    Posts
    12
    The full code is shown below

    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 10000
    
    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!" };
        // 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[])
    {
        int rounds = 0;
        int highest = 0;
        int lowest = INT_MAX;
        float allScore = 0;
        int avg = 0;
    
        int i, j, g = 0;
        struct struc test[MAX_TESTS];
    
        srand((unsigned) time(NULL));
    
        for (;;)
        {
            rounds++;
            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
            }
            char x;
            x = getchar();
            printf("\n Are you ready? Press Enter key to continue. ");
            fflush(stdin);
            while (x != '\n') {}
            while (getchar() != '\n') {}
    
            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 'R' to return to main menu");
                char choice;
                printf(" ");
                myread("%c", &choice);
                if (choice == 'r' || choice == 'R')
                {
                    done = true;
                }
                else
                {
    
                    ///////////////////////// Changes    /////////////
    
                    g = 0;
                    // calculate total score for current round
                    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 (choice == 'S' || choice == 's')
                    {
                        showS = false;
                        if (rounds == 1)
                        {
                            printf(" Final score: %d/100\n", g);    //display round score
                            printf(" ******Player: %s ******\n", name);
                        }
                        else
                        {
                            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: %d/100\n", avg);
                            printf(" ******Player: %s ******\n", name);
                        }
                        unsure = true;
                    }
                    else if (choice == 'P' || choice == 'p')
                    {
                             /// nothing to be done here
                        //we will display next test
                    }
                    else
                    {
                        puts(" Invalid input!");
                        unsure = true;
                    }
    
                    ////////////////////////////////////
    
                }
            }
            if (done)
                break;
        }
    }
    
    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:\n");
                printf(" ");
            }
            else
                printf("\n Invalid input! Please enter 'Y' to return to the main menu:\n");
            printf(" ");
    
            return choiceY(option);    //if enter invalid input recursive call the choiceY function
        }
        return '0';
    }
    
    int main()
    {
        char 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("%c", &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("\n Invalid input! Please select from options 1, 2 or 3\n\n");
            }
            fflush(stdin);
        }
        return 0;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Like I said in your previous thread...
    Facing 2 problems in my C code: Prompt missing + Faulty scores output

    You have a perfectly good myread function, if you use if for everything.

    If you try and mix-and-match, you're in for surprises.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2020
    Posts
    12
    I solved it! It is by changing 'myread' into 'scanf' though. And I have no idea why lol.

  6. #6
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Please initialize all your local variables. Sooner or later you will get burned with garbage data in an uninitialized local variable.

    That in addition to my recommendations in my first response, which Salem also recommended in another thread!

  7. #7
    Registered User
    Join Date
    Nov 2020
    Posts
    12
    Quote Originally Posted by rstanley View Post
    You should a full program with the main() function so we can compile and test the program.

    fflusf() is for output files only, fflush(stdin) should NEVER be used!

    Code:
    srand((unsigned) time(NULL));
    This should be called once in the main() function, not every time quiz() is called.

    Where do you actually call rand()?

    Where is and what is myread()?
    Hi, what should I replace fflush(stdin) with?

  8. #8
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by Eve Wein View Post
    Hi, what should I replace fflush(stdin) with?
    There are several options:

    1) Use fgets() to input the entire line, including the newline, then process the line as needed.

    2) After a getchar():
    Code:
    int ch;
    while ( ( ch = getchar() ) != EOF && ch != '\n' );
    ch should be an int not a char, as getchar() returns an int, and EOF is a full integer, NOT a char!

  9. #9
    Registered User
    Join Date
    Nov 2020
    Posts
    12
    Thank you! The code worked perfectly!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner HiLo game glitches?
    By C22 in forum C++ Programming
    Replies: 2
    Last Post: 10-06-2013, 03:34 PM
  2. Replies: 6
    Last Post: 04-10-2011, 05:12 PM
  3. CPU glitches solved
    By VirtualAce in forum General Discussions
    Replies: 52
    Last Post: 03-29-2011, 07:48 AM
  4. Graphical Glitches
    By Pressure in forum Tech Board
    Replies: 3
    Last Post: 04-27-2005, 07:42 AM
  5. Color Glitches in Console Prog.
    By Darkflame in forum C++ Programming
    Replies: 3
    Last Post: 02-18-2002, 11:52 PM

Tags for this Thread