C 中的 Do-While 循环 - 打印时出错
Do-While loop in C - error at printing
我正在制作一个小程序,它将问题 "Are you an adult?" 的答案作为输入作为这样一个字符:
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
我的目标是,如果答案既不是 y 也不是 n,那么问题应该自行重复。但这似乎有一个错误:
当我回答其他问题(不是 y 或 n)时,问题会打印两次:
你成年了吗?
你
你是成年人吗?
你是成年人吗?
...
为什么会这样?
另外,我尝试过使用 scanf 而不是 getchar 的相同方法,但存在相同的错误。对于这种程序,我应该使用 scanf 还是 getchar,为什么?
谢谢!
实际上,答案中带有 (yes) y 或 (no) n 的额外 '\n' 会被计算在内并打印两次。你只记得得到那个虚拟的'\n'。使用另一个额外的 getchar()
。虚拟 getchar()
是解决此问题的方法。
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
getchar(); //~~~~~~~~~~~~~~~~~~~~> this is what gets the extra '\n'
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
你可以看看我的另一个答案here.You就会有一个清晰的思路。
编辑:正如 Random832 所指出的,在 yes\n
的情况下,ye
被消耗,但 s\n
没有被消耗。因此更好的解决方案是使用 do..while 或 while 循环存储第一个字符并消耗所有其他字符直到 \n
。然后检查第一个字符。或者您可以根据需要存储整个字符串并使用第一个字符来获得答案。
编辑 2:冲洗不是解决此问题的方法。之前我提到过。 iharob 向我指出了这一点。您可以查看这两个答案以获得清晰的思路。
Flushing buffers in C
How to clear input buffer in C?
为了使代码有效,即它可以处理任何输入,您可能需要阅读所有您不认为有效的字符,包括在您输入时发送的 '\n'
按 enter 并刷新输入缓冲区,使用 fflush()
无法做到这一点,因为它仅为输出缓冲区定义,您还应该考虑空行的情况,即当用户按 立即输入,下面的代码就完成了我所描述的一切
#include <stdio.h>
#include <stdbool.h>
bool
adult()
{
char answer;
do {
int chr;
printf("Are you an adult? [y/n] ");
answer = getchar();
if (answer == '\n')
continue;
while (((chr = getchar()) != EOF) && (chr != '\n'));
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
我正在制作一个小程序,它将问题 "Are you an adult?" 的答案作为输入作为这样一个字符:
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
我的目标是,如果答案既不是 y 也不是 n,那么问题应该自行重复。但这似乎有一个错误:
当我回答其他问题(不是 y 或 n)时,问题会打印两次:
你成年了吗? 你 你是成年人吗? 你是成年人吗? ...
为什么会这样? 另外,我尝试过使用 scanf 而不是 getchar 的相同方法,但存在相同的错误。对于这种程序,我应该使用 scanf 还是 getchar,为什么?
谢谢!
实际上,答案中带有 (yes) y 或 (no) n 的额外 '\n' 会被计算在内并打印两次。你只记得得到那个虚拟的'\n'。使用另一个额外的 getchar()
。虚拟 getchar()
是解决此问题的方法。
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
getchar(); //~~~~~~~~~~~~~~~~~~~~> this is what gets the extra '\n'
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
你可以看看我的另一个答案here.You就会有一个清晰的思路。
编辑:正如 Random832 所指出的,在 yes\n
的情况下,ye
被消耗,但 s\n
没有被消耗。因此更好的解决方案是使用 do..while 或 while 循环存储第一个字符并消耗所有其他字符直到 \n
。然后检查第一个字符。或者您可以根据需要存储整个字符串并使用第一个字符来获得答案。
编辑 2:冲洗不是解决此问题的方法。之前我提到过。 iharob 向我指出了这一点。您可以查看这两个答案以获得清晰的思路。
Flushing buffers in C
How to clear input buffer in C?
为了使代码有效,即它可以处理任何输入,您可能需要阅读所有您不认为有效的字符,包括在您输入时发送的 '\n'
按 enter 并刷新输入缓冲区,使用 fflush()
无法做到这一点,因为它仅为输出缓冲区定义,您还应该考虑空行的情况,即当用户按 立即输入,下面的代码就完成了我所描述的一切
#include <stdio.h>
#include <stdbool.h>
bool
adult()
{
char answer;
do {
int chr;
printf("Are you an adult? [y/n] ");
answer = getchar();
if (answer == '\n')
continue;
while (((chr = getchar()) != EOF) && (chr != '\n'));
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}