检查scanf格式而不进行转换

时间:2018-10-31 21:53:45

标签: c++ c scanf

有没有一种方法可以在不使用字符转换的情况下使用scanf检查输入中是否给出了某些特定字符?

int main(void)
{
if(scanf("{ ["))
    printf("GOOD INPUT\n");
else
    printf("BAD INPUT\n");
return 0;
}     

此代码始终提供错误的输入选项(期望scanf返回值为1),但有趣的是,如果我输入的不是期望的字符,则立即给出错误的输入,但是如果我输入的是scanf中指定的内容,则会弹出错误输入完整的输入后,我的输入就不好了。

因此必须等待输入采用指定格式,但是我的问题是:如何检查输入而没有任何转换,并根据输入是否正确输入进行相应的操作?

3 个答案:

答案 0 :(得分:3)

您可以使用scanf%n转换(下面将到目前为止的字符数设置为pos

int pos= -1;
if (scanf("{ [%n", &pos) >=0 && pos>0) 
   printf("GOOD INPUT\n");
else 
   printf("BAD INPUT");

请注意,scanf的返回计数可能是特定于实现的(可能保持为0)。但是pos被分配为scanf的正偏移量,确实得到了{,后跟一些(零个或多个)类似空格的字符,后跟一个[

但是,您可能想要的是一些lexical analysisparsing,那么scanf并不是一个好的解决方案。您最好阅读整行(例如使用fgetsgetline),然后再进行解析。

另请参见scanf(3)man

答案 1 :(得分:2)

scanf(和表亲)返回成功转换次数的计数。如果您指定0次转化,则其返回值将始终为0。

要使用scanf来完成此任务,我可能会使用一些扫描集转换:

char a[2], b[2];
if (scanf("%1[{] %1[[]", &a, &b) == 2)
    printf("Matched");

或者,您可以简化一下:

char a[2];
if (scanf("{ %1[[]", &a) == 1)

无论哪种方式,我们都将每个扫描集指定为仅匹配一个指定的字符,但这仍然是一次转换,因此我们可以查看它是成功还是失败。

不幸的是,我们仍然必须将结果分配到某个地方。 scanf确实支持使用*,例如:“%* s”,告诉它读取字符串,但不将结果存储在任何地方-但是,这样做时,转换不会成功计入返回值中,因此(与之前非常相似)我们无法使用它来确定是否获得匹配项。

答案 2 :(得分:2)

如果 good 输入需要恰好3个字符: { 空格 [,请使用"%*1[ ]"扫描一个空格,并"%n"保存扫描字符数,以确保扫描到达预期的末端。

int main(void) {
  int n = -1;
  scanf("{%*1[ ][%n", *n);
  if (n >= 0) {
    printf("GOOD INPUT\n");
  } else {
    printf("BAD INPUT\n");
  }
  return 0;
} 

我建议先使用fgets()读取输入的,然后解析缓冲区。当发生输入时,这可能会使stdin处于更知名的状态。