为什么这个语句在 while 循环中打印了两次?
Why is this statement printed twice in while loop?
我写了这个简单的练习程序:
#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;
}
当我运行这个的时候,它首先要我输入一个选项。如果我输入 '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$
发生这种情况是因为您键入了一个字母,然后按了回车键。使用另一个 getchar()
吃掉尾随的换行符。
所以改变这个:
k = toupper(getchar());
对此:
k = toupper(getchar());
getchar(); // eat the trailing newline
当用户输入内容时,它会转到 stdin(标准输入)流,系统确保将用户输入的内容存储在内部缓冲区中。所以这就是 你的 代码发生的事情:
所以解决方案是 吃掉尾随的换行符!
彩蛋小贴士:
你应该收到这个:
warning: implicit declaration of function ‘printf’
因为您缺少 IO header,因此您应该在主文件的顶部添加:
#include <stdio.h>
同样你应该添加:
#include <ctype.h> // for toupper()
#include <stdlib.h> // for exit()
另一个解决方案是使用 fgets(), see this question for more C - scanf() vs gets() vs fgets().
我在 scanf()
上遇到了与你类似的问题,我站在你的立场上,所以我当时记下了 solution。
我写了这个简单的练习程序:
#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;
}
当我运行这个的时候,它首先要我输入一个选项。如果我输入 '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$
发生这种情况是因为您键入了一个字母,然后按了回车键。使用另一个 getchar()
吃掉尾随的换行符。
所以改变这个:
k = toupper(getchar());
对此:
k = toupper(getchar());
getchar(); // eat the trailing newline
当用户输入内容时,它会转到 stdin(标准输入)流,系统确保将用户输入的内容存储在内部缓冲区中。所以这就是 你的 代码发生的事情:
所以解决方案是 吃掉尾随的换行符!
彩蛋小贴士:
你应该收到这个:
warning: implicit declaration of function ‘printf’
因为您缺少 IO header,因此您应该在主文件的顶部添加:
#include <stdio.h>
同样你应该添加:
#include <ctype.h> // for toupper()
#include <stdlib.h> // for exit()
另一个解决方案是使用 fgets(), see this question for more C - scanf() vs gets() vs fgets().
我在 scanf()
上遇到了与你类似的问题,我站在你的立场上,所以我当时记下了 solution。