在OS X上xlocale出现问题了吗?

5
我有一个简单的程序,用一系列在命令行上传递的区域设置测试wchar_t和char之间的转换。它通过打印区域设置名称和无法转换的字符串来输出失败转换列表。
我使用clang和libc++构建它。我的理解是,在OS X上,libc ++的命名语言环境支持由xlocale库提供。
我看到了一些意外的失败,以及一些应该失败但没有失败的情况。
以下是程序。
#warning call this program like: "locale -a | ./a.out" or pass \
locale names valid for your platform, one per line via standard input

#include <iostream>
#include <codecvt>
#include <locale>
#include <array>

template <class Facet>
class usable_facet : public Facet {
public:
    // FIXME: use inheriting constructors when available
    // using Facet::Facet;
    template <class ...Args>
    usable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
    ~usable_facet() {}
};

int main() {
    std::array<std::wstring,11> args = {L"a",L"é",L"¤",L"€",L"Да",L"Ψ",L"א",L"আ",L"✈",L"가",L""};

    std::wstring_convert<usable_facet<std::codecvt_utf8<wchar_t>>> u8cvt; // wchar_t uses UCS-4/UTF-32 on this platform

    int convert_failures = 0;
    std::string line;
    while(std::getline(std::cin,line)) {
        if(line.empty())
            continue;

        using codecvt = usable_facet<std::codecvt_byname<wchar_t,char,std::mbstate_t>>;
        std::wstring_convert<codecvt> convert(new codecvt(line));

        for(auto const &s : args) {
            try {
                convert.to_bytes(s);
            } catch (std::range_error &e) {
                convert_failures++;
                std::cout << line << " : " << u8cvt.to_bytes(s) << '\n';
            }
        }
    }

    std::cout << std::string(80,'=') << '\n';
    std::cout << convert_failures << " wstring_convert to_bytes failures.\n";
}

以下是一些正确输出的例子。
en_US.ISO8859-1 : 
en_US.US-ASCII : 

这是一个不符合预期的输出示例。
en_US.ISO8859-15 : 

欧元符号在ISO 8859-15字符集中是存在的,所以不应该出现失败的情况。

以下是我期望但未收到的输出示例。

en_US.ISO8859-15 : ¤
en_US.US-ASCII : ¤

这是ISO 8859-1中存在的货币符号,但在ISO 8859-15中被移除并替换为欧元符号。这种转换不应该成功,但没有发出错误信号。进一步检查此案例时,我发现在两种情况下,“¤”都被转换为0xA4,这是“¤”在ISO 8859-1中的表示。
我没有直接使用xlocale,而是通过libc ++间接使用它。Mac OS X上的xlocale是否存在有错误的区域设置定义?有没有解决方法?还是我看到的问题是由其他原因引起的?
2个回答

3

我猜想您遇到了xlocale系统的问题。我们非常希望能够得到一个错误报告


在10.8版本中仍然看起来有问题 :( 或许有一些方法可以获取xlocale数据并手动修复? - bames53
事实证明,在OS X上,并不是所有的语言环境都使用UTF-32作为wchar_t编码,这非常不幸。 - bames53

-1

我不知道你为什么期望wchar_t是UTF-32或者从哪里听说“OS X的约定是wchar_t是UTF-32”。这肯定是不正确的。wchar_t只有16位宽度。

请参考http://en.wikipedia.org/wiki/Wide_character了解更多关于wchar_t的信息。


3
在 macOS 和大多数 Unix 操作系统上,wchar_t的宽度为32位,而不是16位。 - bames53
1
维基百科提到了一个事实,即在其他平台上它也可以是8位。C++11添加了char16_tchar32_t来解决这个问题,但这与此无关。 - Potatoswatter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接