Why is this statement printed twice in while loop?

亡梦爱人 提交于 2019-12-30 02:26:10

问题


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$

回答1:


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:

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.



来源:https://stackoverflow.com/questions/29502486/why-is-this-statement-printed-twice-in-while-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!