C 实现perror()-issue

C 实现perror()-issue,c,posix,C,Posix,我正在实现与我正在使用的API相当的peror() ISO C标准规定: peror()函数不应更改标准的方向 错误流 但从编程的角度来说,这意味着什么 我目前正在使用fprintf(stderr,…)。使用它是错误的吗?如果是真的,为什么?如果在我的实现中有一些错误(见下文),请为我打分 根据我的解释查看我的C代码: void fooapi_perror(const char *s) { char *emsg; if(s != NULL && *s != '\0')

我正在实现与我正在使用的API相当的
peror()

ISO C标准规定:

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

但从编程的角度来说,这意味着什么

我目前正在使用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);
}

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

例如,printf将使steam成为面向字节的,而wprintf将使steam成为面向广域的

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


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

您可以使用,然后用它来决定是调用
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);
}
void
fooapi_perror(常量字符*s)
{
const char*emsg=fooapi_strerror(fooapi_geterrcode());

如果(fwide(stderr,0)感兴趣,那么您的链接是指向POSIX标准,而不是ISO C标准。我的ISO/IEC 9899:1999副本与您链接的几乎相同-除了您要查询的行!您可能希望从安静的通用措辞
…peror()中修改问题的标题-将
发布到更具体的版本,如
…perror():输出流方向
,因为后者比
perror()
实现本身更重要。