为什么这个语句在 while 循环中打印两次? [英] Why is this statement printed twice in while loop?

查看:54
本文介绍了为什么这个语句在 while 循环中打印两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

#include #include #include #define 类 3#define 学生 4int等级[CLASSES][STUDENTS];int main(void){国际我= 1;图表 t,k;而(我== 1){printf("


菜单:
输入成绩(E)
报告成绩(R)
退出(Q)
你的选择:");k = toupper(getchar());printf("输入的内容... %c
", k);开关(k){案例E":printf("进入成绩..
");休息;案例R":printf("报告成绩...
");休息;案例Q":printf("退出程序...
");退出(0);休息;默认:printf("错误:%c:菜单选项不正确
", k);休息;}}返回0;}

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

host-mb:c_practice host$ ./asd菜单:输入成绩(E)报告成绩(R)退出(Q)您的选择:E输入输入... E进入成绩..菜单:输入成绩(E)报告成绩(R)退出(Q)您的选择:输入已输入...错误:: 不正确的菜单选项菜单:输入成绩(E)报告成绩(R)退出(Q)您的选择:R输入输入... R汇报成绩...菜单:输入成绩(E)报告成绩(R)退出(Q)您的选择:输入已输入...错误:: 不正确的菜单选项菜单:输入成绩(E)报告成绩(R)退出(Q)您的选择:Q输入输入... Q退出程序...主机-mb:c_practice 主机$

解决方案

发生这种情况是因为您键入一个字母然后按 Enter.使用另一个 getchar() 来吃掉尾随的换行符.

所以改变这个:

k = toupper(getchar());

为此:

k = toupper(getchar());获取字符();//吃掉尾随的换行符

当用户输入内容时,它进入stdin(标准输入)流,系统确保将用户输入的内容存储在内部缓冲区中.所以这是您的代码发生的情况:

所以解决方案是吃掉尾随的换行符

<小时>

复活节彩蛋提示:

您应该会收到:

warning: 函数‘printf’的隐式声明

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

#include 

同样,您应该添加:

#include //对于 toupper()#include //对于退出()

另一种解决方案是使用 fgets(),有关更多信息,请参阅此问题C - scanf() vs gets() vs fgets().><小时>

我在使用 scanf() 时遇到了与您类似的问题,我也站在您的立场上,所以我写下了 解决方案当时.

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("


MENU:
Enter the grades(E)
Report Grades(R)
Quit(Q)
Your choice: ");
        k = toupper(getchar());
        printf("Input entered... %c
", k);
        switch(k) {
            case 'E' : 
                printf("Entering the grades..
");
                break;
            case 'R' :
                printf("Reporting the grades...
");
                break;
            case 'Q' :
                printf("Quitting the program...
");
                exit(0);
                break;
            default:
                printf("ERROR: %c: Incorrect menu option
", 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$

解决方案

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.

这篇关于为什么这个语句在 while 循环中打印两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆