2

Im having some problems making my newly started project to work (also im a beginner). For some reason option number 4 in my interactive menu doesn't work and just takes a default route (doesn't output whats inside a file (file directory is fine.).

At this point i've read every forum searching for answer but couldn't modify my code in any way that would work. So I decided to ask you for help. Here is my code:

#include <stdio.h>
#include <stdlib.h>
#define kFileLocation "/Users/patrykpiwowarczyk/Desktop/STUDIA/FoCP/Kodowanie/TestProjektSemestralnyAngielski/TestProjektSemestralnyAngielski/authors.txt"

void options();
void start(void);
void score(void);
void optionz(void);
void author(void);

void pexit(void);

    int main(void)
    {
        char ch;
        int num;
        char option;
        while (1) {
            printf("****Your English Learning Index Cards****\n\n");
            printf("Enter 1-5 of the following options: \n\n");
            options();
            scanf("%c", &option);

            switch (option) {
                case '1':

                    break;
                case '2':

                    break;
                case '3':
                    break;
                case '4':
                    author();
                    break;
                case '5':
                    pexit();
                    break;
                default:
                    printf("Please insert number ranging from 1-5 though... No cheating! \n\n");
                    printf("Press ENTER key to Continue\n");

            }


        }
        return 0;
    }

    void options()
    {
        printf("1. Start Game \n");
        printf("2. View Scoreboard \n");
        printf("3. Options \n");
        printf("4. Author \n");
        printf("5. Exit \n\n");
    }

void author()
{

    char c;
    FILE *authorsFile;


    if ((authorsFile = fopen("/Users/patrykpiwowarczyk/Desktop/STUDIA/FoCP/Kodowanie/TestProjektSemestralnyAngielski/TestProjektSemestralnyAngielski/authors.txt","r")) == NULL)
    {
        printf("FAILED to read the file, maybe check directory?\n");
        exit(1);
    }

    while ((c = fgetc(authorsFile)) != EOF)
    {

        printf("%c", c);
    }

    fclose(authorsFile);


}

void pexit()
{

    puts("Your progress has been saved, see you next time.");
    exit(0);
}

if you could help me in any way I would appreciate it soo much..

Greetings, Patryk Piwowarczyk.

PS: the #define kFileLocation is a leftover from my other tries. Omit it.

  • Does option 4 always fail, even if you type it immediately after starting the program? If not, then the problem can likely be solved by changing `scanf("%c", &option);` to `scanf(" %c", &option);` to remove any preceding whitespace. See [this question](https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer) for further information on removing whitespace with scanf. – Andreas Wenzel Dec 03 '19 at 23:08
  • Menu displays normally. Additionaly typing option 5 works just fine. Only after typing option 4 the default case is activated (instead of case no 4) – Patryk Piwowarczyk Dec 03 '19 at 23:11
  • When you type 4, are you sure that only the default case is activated? Or could it be that the proper case is activated and then the default case is activated immediately afterwards (due to it reading the newline character), without you pressing any further keys? Can you scroll back in the console window to see if anyting else was activated beforehand? – Andreas Wenzel Dec 03 '19 at 23:13
  • Although I can't reproduce it with my Microsoft Visual Studio 2017 compiler, I suspect that your program is working as intended, except for scanf reading a newline character immediately afterwards, which causes the default case to be triggered immediately afterwards. You can also test if I am correct by changing the scanf line as I posted above (by adding a space character to the format string). – Andreas Wenzel Dec 03 '19 at 23:19
  • My guess that the reason why 5 works fine, but not 4, is that 5 causes a program exit, so that the newline character cannot trigger the default case immediately afterwards. – Andreas Wenzel Dec 03 '19 at 23:34
  • Does pressing 1, 2 and 3 also trigger the default case? – Andreas Wenzel Dec 03 '19 at 23:35
  • Pressing 1,2 and 3 also triggers the default case and you were right. Program indeed prints my file and then prints the menu once again. So maybe should I implement another menu on the end of the file printing function? right? Like one that would ask user to choose whether he wants to go back to the menu? Or is there any better way to do this? – Patryk Piwowarczyk Dec 04 '19 at 09:30
  • Also Thank you alot!!! I would never have noticed it! – Patryk Piwowarczyk Dec 04 '19 at 09:32
  • Sorry for repeating comments. I managed to get it to work. Thank you mate :) – Patryk Piwowarczyk Dec 04 '19 at 11:40
  • As I have already stated in my first comment, if my theory is correct, the proper solution to the problem is to simply add a space to the scanf format string, so that scanf discards all whitespace before reading the menu selection character. I have now formulated a proper answer to your question. If that answer is correct, please accept it. If not, please explain exactly how you were able to get it to work instead. – Andreas Wenzel Dec 04 '19 at 16:59

1 Answers1

0

Based on your comments, I conclude the following:

The problem was that scanf correctly wrote the digit into the variable option the first time it was called. However, the second time scanf was called, it immediately returned the newline character from the previous menu selection, instead of waiting for the user to enter another digit. Whenever scanf returned a newline, the default case was triggered.

Therefore, the problem can be best solved by changing the scanf call to the following:

scanf(" %c", &option);

By adding a space to the start of the format string, you instruct scanf to discard all whitespace characters before reading the character. That way, you can insure that a newline will never be written into the option variable.

The problem of scanf reading newline characters instead of discarding them has been discussed in more detail in this question.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • this was exactly the problem. I fixed it using fflush(stdin); function. But your way of fixing it was also fine. – Patryk Piwowarczyk Dec 04 '19 at 18:46
  • @PatrykPiwowarczyk: As far as I know, calling `fflush(stdin)` has no effect on some platforms. See [this question](https://stackoverflow.com/questions/2979209/using-fflushstdin) for further information on why it should not be used. I suggest using my solution instead, which is the proper way to solve this problem. – Andreas Wenzel Dec 04 '19 at 19:23