【问题标题】:Check scanf formating without conversions检查没有转换的scanf格式
【发布时间】:2019-04-05 03:48:22
【问题描述】:

有没有办法在不使用字符转换的情况下使用 scanf 检查输入时是否给出了某些特定字符?

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

这段代码总是给出错误的输入选项(它期望 scanf 返回值为 1),但有趣的是,如果我输入的不是所需的字符,它会立即给出错误的输入,但如果我按照它在 scanf 中指定的方式输入它会爆炸在我输入整个输入之后,我的错误输入。

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

【问题讨论】:

  • 将输入读入某物,然后进行比较。
  • 是的,这是一个选项,但是如果输入可以是两种可能的格式,我有两个 scanf 函数,我需要根据输入的格式决定使用哪一个?
  • 先读取输入而不考虑其实际格式,然后将输入的内容与您需要的格式进行比较。
  • 对于 good 输入,“{”和“[”之间的字符是否需要正好是 1 ' '
  • 对我而言,没有一个空格就足够了重要的部分是字符的顺序,例如 scanf("{ [ , :") 我想将它与这个 scanf("{ [ : ,") 并根据这些字符的顺序在我的程序中决定下一步该做什么

标签: c++ c scanf


【解决方案1】:

您可以使用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 页面

【讨论】:

  • 这里不需要scanf()的返回。 pos = -1; scanf("{ [%n", &pos); if (pos>0) ... 就足够了。
  • 只因为我将pos初始化为-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”,告诉它读取一个字符串,但不要将结果存储在任何地方——但是当你这样做时,该转换不会被计入返回值,所以(很像以前)我们不能用它来确定我们是否得到了匹配。

【讨论】:

    【解决方案3】:

    如果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() 读取 输入,然后解析缓冲区。当 bad 输入发生时,这会使 stdin 处于更好的已知状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 2017-06-28
      • 2012-05-03
      相关资源
      最近更新 更多