代码之家  ›  专栏  ›  技术社区  ›  Kevin

为什么这么叫扫瞄?这是标准的吗?

  •  2
  • Kevin  · 技术社区  · 14 年前

    我在完成K&R练习7.4和7.5时,遇到了一个令人讨厌的“功能”,我不相信标准状态。

    根据K&R,转换规范%c的操作模式

    “下一个输入字符(默认为1)将放置在指定的位置。禁止正常跳过空白;若要读取下一个非空白字符,请使用%1s“

    “下一个输入字符(默认为1)将放置在指定的位置。 ,将禁止正常跳过空白;若要读取下一个非空白字符,请使用%1s“

    void test1()
    {
       char t1, t2;
    
       scanf("%c %c", &t1, &t2);
       printf("%d\n", t1);
       printf("%d\n", t2);
    
       //INPUT is: "b d" (without quotes)
    }
    

    结果t1=98(b)和t2=100(d)。(跳过空白)

    但是,此代码:

    void test2()
    {
       char t1, t2;
    
       scanf("%c", &t1);
       scanf("%c", &t2);
       printf("%d\n", t1);
       printf("%d\n", t2);
    
       //INPUT is: "b d" (without quotes)
    }
    

    结果t1=98(b)和t2=32('')。(空白 不是

    读了原文,我想任何有理智的人都会认为,在对scanf的同一次调用中,(%c),空格跳过被禁止。然而,情况似乎并非如此。

    看来,为了恢复原来的功能,必须完全清空stdin。

    这样行吗?有记录吗?因为我环顾四周,没有看到太多关于这方面的信息。

    作为参考,我在C99中编程。

    6 回复  |  直到 14 年前
        1
  •  3
  •   Joshua Taylor    11 年前

    手册页 scanf 在Linux状态下:

    我相信这消除了这种模糊性: c 一个人就可以 跳过空白;格式字符串中必须有显式空格字符。因此,如果将第二个示例更改为:

    scanf("%c", &t1);
    scanf(" %c", &t1);
    

    第二次呼叫 扫描 将跳过空白,因为显式的空白字符。

        2
  •  13
  •   Michał Trybus    14 年前

    这是因为传递给scanf的字符串中的空格表示空格跳过。 "%c%c" 而不是 "%c %c" ,第一个程序的行为与第二个程序完全相同。

    所以你的问题的答案是:正常的跳跃是 总是

        3
  •  2
  •   stacker    14 年前

    “%c%c”之间的空白表示跳过第一个和第二个字符之间的空白,”%c“在第一个位置表示读取任何字符。

        4
  •  2
  •   Jerry Coffin    14 年前

    否--%c只读取输入的下一个字符,而不管它是什么。与%s形成对比的是,它跳过任何前导空白,然后读取指定数量的字符(在指定数量或遇到空白字符时停止)。

    但是,在第一段代码中,两个%c转换之间的格式字符串中有一个空格。格式流中的空格意味着在尝试下一次转换之前,它应该跳过任何和所有连续的空格。

        5
  •  0
  •   src    14 年前

    从scanf手册页

    • 一系列空白字符(空格、制表符、换行符等;见isspace(3))。此指令匹配输入中的任意数量的空白,包括无空白。

    在第一种情况下,你有这个指令,但在第二种情况下没有。

        6
  •  0
  •   ssegvic    14 年前

    标准(C9899:TC3)表示,对于%c和其他一些规范,不会跳过空白(7.19.6.2.8)。