我正在实现与我正在使用的API等价的perror()。
perror() ISO 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);
}发布于 2012-07-14 16:15:38
每个C流都有一个属性--“定向”--“面向宽”或“面向字节”,这是由第一次操作决定的。当流没有“定向”(.Calling)时,允许您更改蒸汽的方向--任何与流向冲突导致未定义行为的函数。
例如,printf会让蒸汽变成面向字节的,而wprintf则会导致蒸汽是面向宽的。
就你的问题而言,恐怖不应该改变它的流向。
因此,在您的代码中,如果perror使用的流已经有了一个方向,那么您应该确保您没有调用一个方向与流的当前方向相冲突的函数。
发布于 2012-07-14 17:23:38
您可以使用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);
}注意:当流尚未获得方向时,这不符合“不更改流方向”的要求,因为没有方法可以不定向流,也没有办法在不给流定向的情况下向流发送输出。在这种情况下,perror会使用肮脏的攻击(复制底层文件描述符!)也许我们应该把它记在“标准C宽字符支持并不真正适合于目的”之下,然后继续前进。
切向kibitz:fooapi_strerror应该返回一个指向字符串常量的指针,而不是必须是freed的指针。
https://stackoverflow.com/questions/11484950
复制相似问题