为什么这个语句在while循环中打印两次?

gix*_*xer 5 c io loops while-loop getchar

我写了这个简单的练习程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它首先要求我输入一个选项.如果我输入'E'或'R',它会进入相应的'case'块,但是在while循环中的下一次迭代中,它不会等我输入我的选择.相反,它假设我输入"NULL"并第三次询问我的提示.每次进入选择时都会发生这种情况.这是该程序的输出.我在这里错过了什么?

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$
Run Code Online (Sandbox Code Playgroud)

gsa*_*ras 13

这是因为您键入一个字母,然后按Enter键.使用另一个getchar()来吃尾随换行符.

所以改变这个:

k = toupper(getchar());
Run Code Online (Sandbox Code Playgroud)

对此:

k = toupper(getchar());
getchar(); // eat the trailing newline
Run Code Online (Sandbox Code Playgroud)

当用户输入内容时,它会转到stdin(标准输入)流,系统会确保存储用户在内部缓冲区中输入的内容.所以这是你的代码发生了什么:

在此输入图像描述

所以解决方案是吃尾随换行!


复活节彩蛋提示:

你应该收到这个:

warning: implicit declaration of function ‘printf’
Run Code Online (Sandbox Code Playgroud)

因为你缺少IO头,所以你应该在主文件的顶部添加:

#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)

同样你应该添加:

#include <ctype.h>  // for toupper()
#include <stdlib.h> // for exit()
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是使用fgets(),查看这个问题以获得更多C - scanf()vs gets()vs fgets().


scanf()和你的问题有类似的问题而且我在你的鞋子里,所以我当时写下了解决方案.