5

I wrote this simple program for practise:

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

#define CLASSES 3
#define STUDENTS 4
int grades[CLASSES][STUDENTS];

int main(void)
{
    int i = 1;
    char t,k;
    while(i == 1)
    {
        printf("\n\n\nMENU:\nEnter the grades(E)\nReport Grades(R)\nQuit(Q)\nYour choice: ");
        k = toupper(getchar());
        printf("Input entered... %c\n", k);
        switch(k) {
            case 'E' : 
                printf("Entering the grades..\n");
                break;
            case 'R' :
                printf("Reporting the grades...\n");
                break;
            case 'Q' :
                printf("Quitting the program...\n");
                exit(0);
                break;
            default:
                printf("ERROR: %c: Incorrect menu option\n", k);
                break;
        }

    }
    return 0;
}

When I run this, it first asks me to enter a choice. If I enter 'E' or 'R', it goes into the respective 'case' block but in the next iteration within the while loop, it doesn't wait for me to enter my choice. Instead it assumes I entered "NULL" and asks for my prompt third time. This keeps happening everytime I enter a choice. Here is the output of this program. What am I missing here?

host-mb:c_practice host$ ./asd



MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: E
Input entered... E
Entering the grades..



MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: Input entered...

ERROR:
: Incorrect menu option



MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: R
Input entered... R
Reporting the grades...



MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: Input entered...

ERROR:
: Incorrect menu option



MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: Q
Input entered... Q
Quitting the program...
host-mb:c_practice host$
gsamaras
  • 71,951
  • 46
  • 188
  • 305
gixxer
  • 814
  • 1
  • 10
  • 25

1 Answers1

13

This happens because you type a letter and then you press enter. Use another getchar() to eat the trailing newline.

So change this:

k = toupper(getchar());

to this:

k = toupper(getchar());
getchar(); // eat the trailing newline

When the user inputs something, it goes to the stdin (standard input) stream and the system makes sure to store what the user typed in a internal buffer. So here is what happened with your code:

enter image description here

So the solution is to eat the trailing newline!


Easter eggs tips:

You should receive this:

warning: implicit declaration of function ‘printf’

because you lack of the IO header, thus you should add in the top of your main file this:

#include <stdio.h>

Similarly you should add:

#include <ctype.h>  // for toupper()
#include <stdlib.h> // for exit()

Another solution would be to use fgets(), see this question for more C - scanf() vs gets() vs fgets().


I had a similar issue to yours with scanf() and I was in your shoes, so I had written down the solution at the time.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • That helped. Thanks. So everytime I expect an "enter" from the user, I need to eat it using getchar(). – gixxer Apr 07 '15 at 22:36
  • Exactly! Nice catch and nice question, you got my +1. @gixxer – gsamaras Apr 07 '15 at 22:36
  • I guess there is another solution, instead of using getchar() 2 times, I can use gets() and strip the '\n' from the input. – gixxer Apr 07 '15 at 22:37
  • Correct @gixxer, see my edit! Use `fgets()` instead! – gsamaras Apr 07 '15 at 22:40
  • @gixxer you probably got it by now, but I added a pic that I believe will help future readers, hope you like it! :D – gsamaras Apr 07 '15 at 23:05
  • @gixxer Actually, double `getchar()` call may be very unwise. If a user enters 0 or 2+ characters and then presses enter, the program will start to behave strangely. So, it's better to use this `k = toupper(getchar()); if (k != '\n') while (getchar() != '\n') {}` or [f]gets() call. – HolyBlackCat Apr 04 '16 at 16:23