考虑以下简约代码片段:
#include <stdio.h>
#include <errno.h>
#include <locale.h>
int main() {
const char *locale = setlocale(LC_ALL, "");
if (errno == ENOENT) {
printf("Locale %s unavailable.\n", locale ? locale : "<unknown>");
} else if (errno) {
printf("setlocale() failed: errno = %d\n", errno);
perror("setlocale() failed");
}
if (locale) {
printf("Current locale: %s\n", locale);
}
return errno;
}
它可以在许多 UNIX 机器(Solaris 8、Debian Linux 8、OpenBSD 5.8)上成功运行。不过,也有一些异常(exception)。
根据manual page ,如果进程环境(LC_ALL
等)指定的语言环境不可用(即相应的文件丢失并且需要使用 localegen
或类似工具生成)。测试表明errno
在本例中设置为 ENOENT
,但在 Debian 7 框之一上 setlocale
返回有效的非 NULL
区域设置字符串and将errno
设置为ENOENT
。
Cygwin 表现出另一个奇怪的行为:对于每个单字节西里尔语言环境(ru_RU.CP1251
、ru_RU.CP866
、ru_RU.KOI8-R
、ru_RU.ISO-8859-5
)、setlocale
返回正确的区域设置字符串并且 将 errno
设置为 EILSEQ
。同时,ru_RU.UTF-8
不受影响。
如何进一步诊断上述病例?
最佳答案
POSIX does not specify setlocale
如何影响 errno
(请参阅错误部分,其中显示“未指定错误”)。在调用 setlocale
后,您可以安全地忽略 errno
的值。
setlocale
的实现永远不应该触及 errno
,但您测试的某些实现似乎在这方面存在错误。我建议您针对提供错误 setlocale
实现的项目提交错误报告。
关于c - setlocale 在返回非 NULL 值时引发 errno,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33668695/