【发布时间】:2021-12-17 22:40:01
【问题描述】:
我正在尝试写入一个程序,该程序从终端接收一个整数并安全地检查它是否真的是一个 int 以及它是否等于或介于 0 和 5 之间。代码还应该具有重试逻辑。
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
int input;
char i[3];
char *p;
while(fgets(i, (sizeof(i)),stdin)){
input=strtol(i,&p,10);
if(input<0 || input>5 || p==i || (*p)!='\n'){
printf("please enter a integer larger or equal to 0 or smaller or equal to 5\n");
}
else{
printf("%d",input);
break;
}
}
}
我遇到的问题是,如果我输入的字符多于fgets() 读取的字符,例如“aaaaa”,我会得到输出:
please enter a integer larger or equal to 0 or smaller or equal to 5
please enter a integer larger or equal to 0 or smaller or equal to 5
please enter a integer larger or equal to 0 or smaller or equal to 5
我假设问题是fgets 未读取的字符留在缓冲区中,并在触发 if 语句并因此重复输出的后续迭代中被读取。我假设解决方案是以某种方式清除缓冲区,但从我读过的fflush() 来看是不允许的。有没有一种简单的方法来清除缓冲区?如果这确实是问题的问题,你会怎么做?
【问题讨论】:
-
"有没有简单的方法来清除缓冲区?" --> 是的,
scanf("%*[^\n]"); scanf("%1[\n]");或通常的fgetc()while循环。棘手的部分是要知道缓冲区是否需要清除,因为这取决于您需要代码的迂腐程度。例如fgets()在输入包含 空字符 或输入错误时出现问题。 -
如果输入字符串不包含换行符,还有更多等待读取。
fgets最多读取并包括下一个换行符,取决于缓冲区大小和 EOF。 -
如果你只取一个数字,那么你根本不需要
strtol或fgets。使用fgetc读取一个字符并将其与'0'进行比较。 (例如,c = getchar(); input = c - '0';然后使用while( (c = getchar()) != EOF && c != '\n' );消耗该行的其余部分 -
你可能想看看我在this answer to another question末尾写的函数
get_int_from_user。我相信这个函数可以满足你的所有需求,除了检查输入是否在0和5之间,你必须自己做。 -
永远不要吝啬你的输入缓冲区。特别是如果您试图在面对输入错误时保持稳健。您正在尝试处理用户可以键入 anything 的情况。因此,您必须假设用户可能键入了多个字符。因此,让您的输入缓冲区
i[]比您希望用户键入的任何合理长的行都大得多。我至少会声明char i[512];,或者这些天可能是char i[1024];。内存很便宜!
标签: c