【问题标题】:Why scanf can't parse the input separate by / mark?为什么scanf不能用/标记单独解析输入?
【发布时间】:2016-09-26 11:36:00
【问题描述】:

这是我学习scanf函数时的程序:

#include <stdio.h>
int main(int argc, char *argv[]) {
    int day, year;
    char monthName[20];

    printf("separate day by /\n");
    scanf("%d/%s/%d", &day, monthName, &year);
    printf("%d %s %d\n", day, monthName, year);

    printf("separate day by blank\n");
    scanf("%d%s%d", &day, monthName, &year);
    printf("%d %s %d\n", day, monthName, year);
    return 0;
}

输入输出如下:

separate day by /
3/Dec/2016
3 Dec/2016 0
separate day by blank
3 Dec 2016
3 Dec 2016

为什么会出现第二个 / 标记和零字符?有什么方法或工具可以分析此类问题吗?

【问题讨论】:

  • 第一步是检查scanf的返回值。如果它不返回 3(在这种情况下),它还没有设置所有变量。
  • %s/ --> %19[^/]/
  • @BLUEPIXY 我想你的想法也是正确的,这使得scanf识别/标记。
  • 编译时,始终启用所有警告。除其他事项外,main() 的参数未使用,因此签名应为:int main( void )

标签: c scanf


【解决方案1】:

这是因为您的 %s 在第一个 / 字符之后得到了所有内容。所以当你的%d 开始阅读时,什么都没有了。

您可以通过这样做清楚地理解该输出:

printf("separate day by /\n");
scanf("%d/%s/%d", &day, monthName, &year);
printf("%d---%s---%d\n", day, monthName, year);

产量:

separate day by /
3/Dec/2016
3---Dec/2016---0

scanf 没有像您预期的那样尊重第二个/ 的原因是因为%s 不会在/ 处停止,它只在空白字符处停止。从docs查看这个:

任意数量的非空白字符,在第一个停止 找到空白字符。终止空字符是 自动添加到存储序列的末尾。

【讨论】:

    【解决方案2】:

    您需要将格式字符更改为%[...] 以指定接受哪些字符,而不是%s 使用的默认字符。

    您还需要指定缓冲区大小以防止缓冲区溢出。

    用途:

    "%d/%19[^/]/%d"
    

    或者只使用strptime

    【讨论】:

      【解决方案3】:
      1. 好吧,scanf()可以处理用斜杠 ('/') 分隔的字段的输入。只是不适用于字符串(这对你来说很不幸)。
      2. 您看到的是因为您对字符串使用了无效的分隔符(斜杠)。 scanf() 只接受空格(空格、制表符、换行符)作为字符串的分隔符。这是因为一个字符串可能包含许多不同的字符(当然你可能会问为什么一个有效的字符串不应该包含一个空格......好吧,创建者必须选择一些个字符。很多新手程序员在无法使用scanf()...获取带有空格的字符串时偶然发现了这一点)
      3. 对于数字类型,scanf() 可以使用更广泛的分隔符。您可以将所有非法表示数字的字符用作分隔符(整数和实数的确切有效字符集不同)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-12
        • 1970-01-01
        • 2010-09-18
        相关资源
        最近更新 更多