我有一个C++应用程序,我移植到MacOSX(特别是,10.6).该应用程序大量使用C++标准库和提升.我最近在应用程序中观察到一些我很难理解的破损.
基本上,boost文件系统库在程序运行时抛出运行时异常.通过一些调试和谷歌搜索,我将违规调用减少到以下最小程序:
#include <locale>
int main ( int argc, char *argv [] ) {
std::locale::global(std::locale(""));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我通过g ++运行并在LANG=en_US.UTF-8设置的环境中执行生成的程序时,此程序失败(当我创建新的控制台窗口时,我的计算机上的程序是默认bash会话的一部分).清除环境变量(setenv LANG=)允许程序无问题地运行.但我很惊讶我在默认配置中看到了这种破坏.
我的问题是:
为了完整起见,我应该指出,通过'open'命令(或从Finder)启动时,合成此代码的程序会崩溃,但是当Xcode在调试模式下运行程序时则不会崩溃.
编辑 10.6.1上面代码给出的错误是:
$ ./locale terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid Abort trap
我正在编写一个处理文件和目录的可移植库.我想使用UTF-8作为输入(目录路径)和输出(文件路径).问题是,Windows让我可以选择使用UTF-16-UCS-2和代码页.所以我必须将我的所有UTF-8字符串转换为UTF-16,将它们传递给WinAPI,然后将结果转换回UTF-8.C++ 11似乎<locale>只为此提供了库,除了我所理解的,没有任何预定义的特化使用UTF-8作为内部(即我的)编码 - 最接近的是UTF-16到UTF -8,这与我想要的完全相反.所以这是第一个问题:
1)如何使用codecvt thingamajigs将我的UTF-8字符串转换为UTF-16进行WinAPI调用,UTF-16结果返回UTF-8?
另一个问题:我也在瞄准Linux.在Linux上,对许多不同的语言环境有很好的支持 - 我不希望有任何不同.希望每个人都在他们的Linux机器上使用UTF-8,但没有严格的保证.所以我认为扩展上面特定于Windows的行为并始终执行UTF-8到系统区域设置编码是一个好主意.除了我没有看到在C++ 11的<locale>库中有任何方法来获得当前的系统编码!默认的std :: locale构造函数使用自己定义的语言环境,如果不这样做,它将返回经典的"C"语言环境.并且没有其他我知道的吸气剂.所以这是第二个问题:
2)如何检测当前系统区域设置?什么东西<locale>?也许一些标准的C库函数,或者(在这种情况下可移动性较差)POSIX API中的东西?
我有一个简单的程序,它使用在命令行上传递给它的一系列语言环境来测试wchar_t和char之间的转换.它通过打印出语言环境名称和无法转换的字符串输出失败的转换列表.
我正在使用clang和libc ++构建它.我的理解是libc ++的命名语言环境支持由OS X上的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; // …Run Code Online (Sandbox Code Playgroud)