【问题标题】:Implementing perror() - issue实施 perror() - 问题
【发布时间】:2012-07-15 01:31:31
【问题描述】:

我正在实现 perror() 等效于我正在使用的 API。

perror() ISO C std doc 说:

perror() 函数不应改变标准的方向 错误流。

但以编程方式,这意味着什么?

我目前正在使用fprintf(stderr, .. )。是误用了吗?如果是真的,为什么?如果我的实现中有一些错误(见下文),请给我点。

根据我的解释查看我的 C 代码:

void
fooapi_perror(const char *s)
{
  char *emsg;

  if(s != NULL && *s != '\0')
    fprintf(stderr, "%s: ", s);

  emsg = fooapi_strerror(GetLastErrorCode()); 
  fprintf(stderr, "%s\n",  emsg); 
  free(emsg);
}

【问题讨论】:

  • 有趣,您的链接是 POSIX 标准,而不是 ISO C 标准。我的 ISO/IEC 9899:1999 副本与您链接的副本几乎相同 - 除了您要查询的行!
  • 您可能希望将问题的标题从安静的通用措辞 ... perror() - issue 修改为更具体的措辞,例如 ... perror(): output stream orientation,因为它更多地是关于后者而不是关于 perror() 实现本身.

标签: c posix


【解决方案1】:

每个 C 流都有一个属性 - “面向”或“面向宽”或“面向字节”的“方向”,这是由该流上的第一个操作确定的。当流没有“方向”时,您可以更改蒸汽的方向。调用方向与流方向冲突的任何函数会导致未定义的行为。

例如,printf 会使蒸汽变成面向字节的,而 wprintf 会使蒸汽变成面向宽的。

就您的问题而言,perror 不应改变其流的方向。

所以在你的代码中,如果错误使用的流已经有一个方向,你应该确保你没有调用一个方向与流的当前方向冲突的函数。

【讨论】:

    【解决方案2】:

    您可以使用fwide(3) 确定流的方向,并使用它来决定是调用fprintf 还是fwprintf

    void
    fooapi_perror(const char *s)
    {
        const char *emsg = fooapi_strerror(fooapi_geterrcode());
    
        if (fwide(stderr, 0) <= 0) {
            // byte-oriented or not yet oriented
            if (s && *s)
                fprintf(stderr, "%s: %s\n", s, emsg);
            else
                fprintf(stderr, "%s\n", emsg);
        } else {
            // wide-oriented
            if (s && *s)
                fwprintf(stderr, L"%s: %s\n", s, emsg);
            else
                fwprintf(stderr, L"%s\n", emsg);
        }
    
        free(emsg);
    }
    

    注意:当流尚未获得方向时,这不符合“不改变流方向”的要求,因为没有办法un-定位流,也没有任何方法可以在不给它方向的情况下将输出发送到流。 The GNU libc implementation of perror 在这种情况下采用了一种肮脏的技巧(复制底层文件描述符!)也许我们应该将其归结为“无论如何标准 C 宽字符支持并不真正适合目的”并继续前进。

    Tangential kibitz:fooapi_strerror 应该返回一个指向字符串常量的指针,而不是必须是 freed 的指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 2013-09-16
      • 1970-01-01
      • 2016-11-28
      • 2015-05-11
      • 1970-01-01
      相关资源
      最近更新 更多