c - setlocale 在返回非 NULL 值时引发 errno

标签 c posix locale errno setlocale

考虑以下简约代码片段:

#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区域设置字符串anderrno设置为ENOENT

Cygwin 表现出另一个奇怪的行为:对于每个单字节西里尔语言环境(ru_RU.CP1251ru_RU.CP866ru_RU.KOI8-Rru_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/

相关文章:

java - 调试JVM崩溃(如何找到底层C代码中的错误?)

java - 仅具有 ISO 日历的区域设置

从命令行运行程序时出现 C++ 错误 "failure: locale::facet::_S_create_c_locale name not valid"

c - 在 ARM 平台上,如何访问在内存中正确对齐的字符串的各个字符?

python - 如何获取子进程的打开文件?

java - 我需要为 taglib fmt :formatDate 添加日期翻译

c - 字符串数组、strcpy 和字符串的问题

c - 从内联汇编调用函数时针对符号重定位 R_X86_64_PC32

c - c - 如何在文件中写入两个字符串,用空格或逗号分隔?

c - getnameinfo 的签名在 glibc 版本之间发生变化,我该如何匹配它?