【问题标题】:What's the meaning of the %m formatting specifier?%m 格式说明符的含义是什么?
【发布时间】:2014-01-01 20:59:09
【问题描述】:

此代码的输出打印出“成功”。

printf("%m\n");

【问题讨论】:

    标签: c printf glibc errno format-specifiers


    【解决方案1】:

    m 转换说明符不是 C,而是printf 的 GNU 扩展:

    来自 GNU 文档:

    http://www.gnu.org/software/libc/manual/html_node/Other-Output-Conversions.html

    '%m' 转换打印与 errno 中的错误代码对应的字符串。请参阅错误消息。因此:

    fprintf (stderr, "can't open `%s': %m\n", filename);
    

    相当于:

    fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));
    

    “%m”转换是 GNU C 库扩展。

    所以:

    printf("%m\n", d);
    

    等价于

    printf("%s\n", strerror (errno), d);
    

    相当于

    printf("%s\n", strerror (errno));
    

    请注意,%m 不需要参数。这里printf("%m\n", d)printf("%s\n", strerror (errno), d) 的参数比需要的多:printf 如果有额外的尾随参数,它们只会被评估和忽略。

    【讨论】:

    • 我认为最有趣的部分是 printf not 需要为每个 %m 添加一个额外的参数。
    【解决方案2】:

    其实printf()关于%m的手册很简洁:

    m      (Glibc extension; supported by uClibc and musl.)  Print output
                  of strerror(errno).  No argument is required.
    

    但是 strerror() 在多线程程序中有一个问题:它不可重入。线程安全版本是strerror_r()

    GLIBC implementation 的一点研究表明,%m 实际上等同于 strerror_r()。因此 %m 是线程安全的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-22
      • 2013-06-22
      • 1970-01-01
      • 2010-11-03
      • 2012-01-05
      • 2017-02-27
      • 2012-01-31
      • 1970-01-01
      相关资源
      最近更新 更多