0

I'm new to C and I'm building a quiz game, every time you answer right your score gets higher, however there is a bug that i was not able to find which is even if you answer correctly the code will tell you that you are wrong and moves to the next question in the end you will always get a score of 0/3. my question is what is the reason that is preventing my code from determining that the answer is right, why does it always go to the else statement which is wrong.

this is the code

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
    char questions[][100] = {
        "\n1. what company was the first to create a foldable phone? ",
        "\n2. what company was the first to create a foldable laptop? ",
        "\n3. what company was the first to create a full electric car? "
    };

    char options[][100] = {
        "\nA. apple, B. oppo, C. samsung, D. motorolla",
        "\nA. Asus, B. MSI, C. Microsoft, D. Gygabyte",
        "\nA. mazda, B. chevrollet, C. toyota, D. Tesla"
    };

    char answers[] = {'C', 'A', 'D'};

    int score = 0;
    char ans;

    for (int i = 0; i < sizeof(questions) / sizeof(questions[0]); i++)
    {
        printf("%s", questions[i]);
        printf("%s", options[i]);

        printf("\n\nwhat is your answer? ");
        scanf("%c", &ans);
        scanf("%c");

        ans = toupper(ans);

        if (ans == answers[i])
        {
            score += 1;
            printf("\nthat's right!");
            printf("\nnext question\n");
        }
        else
        {
            printf("\nwrong!");
            printf("\nnext question\n");
        }
    }

    printf("\n\nthe correct answers are:  ");
    for (int i = 0; i < sizeof(questions) / sizeof(questions[0]); i++)
    {
        printf("%c  ", answers[i]);
    }

    printf("\nyour score is: %d/3", score);
}

ans is the user guess. if anyone have the solution for this i would really appreciate it. thanks in advance.

Chris
  • 26,361
  • 5
  • 21
  • 42
  • 5
    `scanf("%c", &ans);` -> `scanf(" %c", &ans);` You need a space before `%c` to skip leading whitespace. The second `scanf("%c");` should be removed. – Retired Ninja Sep 13 '22 at 23:25
  • Minor suggestion: leave the newlines out of your questions and options strings. That's a presentation detail, not data. – Chris Sep 14 '22 at 01:02
  • It's bad practice to embed newlines in strings held in arrays. That's what the format-string for printf provides. You only need 1 `printf()` for any continual block of output. So removing the newlines from your arrays. your first three output can reduce to `printf ("\n%s\n%s\nWhat is your answer: ", questions[i], options[i]);` Since you immediately follow with an input call, the output buffer will be flushed ensuring your question is visible. If that were not the case, you would include `fflush(stdout);` after the `printf()`. – David C. Rankin Sep 14 '22 at 01:20
  • 1
    @Milad Bannourah, Tip: "what is the bug that is preventing this C code from determining the right answer?" ---> **Much faster** to enable all warnings and get rapid feedback from a good compiler about `scanf("%c");`. Or take the slow route and post on SO. Your call. – chux - Reinstate Monica Sep 14 '22 at 01:37

1 Answers1

4

ok , so you have only one problem in your code and a warning .

in these 2 lines :

scanf("%c", &ans);
scanf("%c");

when the user enter a char like a and press enter , the first scanf will get a successfully but the second scanf("%c"); is incorrect as you are telling the function to get a character from the input and store it but where ? , it gave me undefined behavior .

note that , in order to clear the buffer after reading one char , you can simply write instead of the above 2 lines , these lines :

scanf("%c", &ans);
fgets(dummy, sizeof(dummy), stdin);

where fgets(dummy, 20, stdin); will read any chars there in the buffer so as to clear it.

also there is a warning in this line ans = toupper(ans); as the warning in my compiler says :

Clang-Tidy: Narrowing conversion from 'int' to signed type 'char' is implementation-defined

as the function called toupper takes int and returns int but you are storing the result into a char , so either cast the result as ans = (char)toupper(ans); or you can use _toupper which takes char and returns char like ans = _toupper(ans);

and this is the full code with these only 2 edits :

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
    char questions[][100] = {"\n1. what company was the first to create a foldable phone? ",
                             "\n2. what company was the first to create a foldable laptop? ",
                             "\n3. what company was the first to create a full electric car? "};

    char options[][100] = {"\nA. apple, B. oppo, C. samsung, D. motorolla",
                           "\nA. Asus, B. MSI, C. Microsoft, D. Gygabyte",
                           "\nA. mazda, B. chevrollet, C. toyota, D. Tesla"};

    char answers[] = {'C', 'A', 'D'};

    int score = 0;
    char ans, dummy[20];

    for (int i = 0; i < sizeof(questions) / sizeof(questions[0]); i++)
    {
        printf("%s", questions[i]);
        printf("%s", options[i]);

        printf("\n\nwhat is your answer? ");
        scanf("%c", &ans);
        fgets(dummy, sizeof(dummy), stdin);

        ans = _toupper(ans);

        if (ans == answers[i])
        {
            score += 1;
            printf("\nthat's right!");
            printf("\nnext question\n");
        }
        else
        {
            printf("\nwrong!");
            printf("\nnext question\n");
        }
    }

    printf("\n\nthe correct answers are:  ");
    for (int i = 0; i < sizeof(questions) / sizeof(questions[0]); i++)
    {
        printf("%c  ", answers[i]);
    }
    printf("\nyour score is: %d/3", score);
}

and this is the output :

1. what company was the first to create a foldable phone?
A. apple, B. oppo, C. samsung, D. motorolla

what is your answer?c

that's right!
next question

2. what company was the first to create a foldable laptop?
A. Asus, B. MSI, C. Microsoft, D. Gygabyte

what is your answer?a

that's right!
next question

3. what company was the first to create a full electric car?
A. mazda, B. chevrollet, C. toyota, D. Tesla

what is your answer?d

that's right!
next question


the correct answers are:  C  A  D
your score is: 3/3
Process finished with exit code 0
abdo Salm
  • 1,678
  • 4
  • 12
  • 22
  • 1
    Only one compiler I can think of allows `fflush(stdin)` as a *non-standard* language extension. That makes your code near 100% non-portable. If the questioner is not using that particular compiler -- see the comment by @chux-ReinstateMonica above. – David C. Rankin Sep 14 '22 at 01:24
  • @chux-ReinstateMonica , thank you for revising my answer , I actually did read about it now and I agree with and I edited the code according to your suggestion – abdo Salm Sep 14 '22 at 01:31
  • 1
    @DavidC.Rankin , I agree with you , I edited the code and instead of `fflush` , I used the `fgets` method – abdo Salm Sep 14 '22 at 01:31
  • 1
    @chux-ReinstateMonica , the second one of course is more convenient and easier to read , I edit that also right now . – abdo Salm Sep 14 '22 at 01:35
  • 1
    Very good job with an informative and well formatted answer. Keep up the good work. – David C. Rankin Sep 14 '22 at 07:02