我没有太多时间,而且很多关于stdin
的内容只会提出比现阶段更多的问题。我希望测试使用scanf
的多个实例传递的多种类型的命令。
如果我这样做:
char inputChar;
char inputChars[15] = { NULL };
int inputInt;
double inputDec;
if(scanf("%c %d %lf",&inputChar,&inputInt,&inputDec) == 3) {
...
}
else if(scanf("%c %d %s",&inputChar,&inputInt,&inputChars) == 3) {
...
}
else if(scanf("%c %d",&inputChar,&inputInt) == 2) {
...
}
else if(scanf("%c",&inputChar) == 1) {
...
}
else {
...
}
然后键入单个字符并按Enter键,控制台会等到我输入另一个值,然后再评估是否匹配。
更新
这似乎工作得很好,除非它希望您在使用时输入完美。如果用户键入aa
,然后在按Enter键之前将其更改为a 10
,则会与第4次评估相匹配。这有两个原因:
aa
应该被过滤到第5次评估中。修订代码:
char input[50] = { NULL };
char inputChar = NULL;
char inputChars[15] = { NULL };
int inputInt;
double inputDec;
printf("Input String:\n>");
fgets(input,sizeof(input),stdin);
if(sscanf(input,"%c%d %lf",&inputChar,&inputInt,&inputDec) == 3) { }
else if(sscanf(input,"%c%d%s",&inputChar,&inputInt,&inputChars) == 3) { }
else if(sscanf(input,"%c%d",&inputChar,&inputInt) == 2) { }
else if(sscanf(input,"%c",&inputChar) == 1) { }
else { }
做这样的事情表明退格没有被过滤掉:
for(int i=0;i<50;i++) {
if(input[i] == (char) 10) { break; }
printf("\n%c %d",(char) input[i],(int) input[i]);
}
因此看起来fgets
不在图片中。
答案 0 :(得分:2)
语句按顺序执行。所以它是第一个等待更多输入的scanf
调用。如果输入与第一个呼叫不匹配,则下一个scanf
呼叫将全部开始,等待输入。等等。
相反,您应该使用fgets
来阅读整行,然后在该行上使用sscanf
。
答案 1 :(得分:1)
请解释“清除输入缓冲区”的含义。你的意思是_flushall在它们发生之前擦除了我的击键吗?怎么会这样呢?也许你的意思是你已经从线上读过了你需要的数据,而你并不关心线路的其余部分。在这种情况下,我假设您希望“阅读并丢弃所有字符,包括下一个换行符”。我有一个便携式机制来做到这一点:
for (int c = getchar(); c >= 0 && c != '\n'; c = getchar());
您可能还希望阅读this related answer。
编辑:我刚刚发现你想要的行为可能表达如下:
char inputChar;
char inputChars[15] = { NULL };
int inputInt;
double inputDec;
int x = scanf("%c%d", &inputChar, &inputInt);
if (x == 2 && scanf("%lf",&inputDec) == 1) {
...
}
else if (x == 2 && scanf("%14s", inputChars) == 1) {
...
}
else {
...
}
答案 2 :(得分:0)
可能不是最好的方法,但它有效。
使用iostream
库运行getline(std::cin,input);
来捕获std::string input
的输入,然后在sscanf
上多次使用input.c_str()
。