首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现perror() -问题

实现perror() -问题
EN

Stack Overflow用户
提问于 2012-07-14 15:25:00
回答 2查看 1.1K关注 0票数 3

我正在实现与我正在使用的API等价的perror()

perror() ISO doc说:

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

但从程序上讲,这意味着什么呢?

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

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

代码语言:javascript
复制
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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-14 16:15:38

每个C流都有一个属性--“定向”--“面向宽”或“面向字节”,这是由第一次操作决定的。当流没有“定向”(.Calling)时,允许您更改蒸汽的方向--任何与流向冲突导致未定义行为的函数。

例如,printf会让蒸汽变成面向字节的,而wprintf则会导致蒸汽是面向宽的。

就你的问题而言,恐怖不应该改变它的流向。

因此,在您的代码中,如果perror使用的流已经有了一个方向,那么您应该确保您没有调用一个方向与流的当前方向相冲突的函数。

票数 9
EN

Stack Overflow用户

发布于 2012-07-14 17:23:38

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

代码语言:javascript
复制
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);
}

注意:当流尚未获得方向时,这不符合“不更改流方向”的要求,因为没有方法可以不定向流,也没有办法在不给流定向的情况下向流发送输出。在这种情况下,perror会使用肮脏的攻击(复制底层文件描述符!)也许我们应该把它记在“标准C宽字符支持并不真正适合于目的”之下,然后继续前进。

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11484950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档