C ++ std :: locale(“ en”)在iOS上引发异常

时间:2018-08-21 12:52:32

标签: c++ ios c++11

在iOS上,当我尝试从有效标识符构造C ++语言环境时,我的程序崩溃:

  

由于未捕获的异常'collat​​e_byname :: collat​​e_byname无法为en构造',终止了应用程序,原因:'collat​​e_byname :: collat​​e_byname无法为en构造'

在此行:

std::locale loc("en");

这在其他平台上工作正常。这是平台上存在的有效语言环境标识符(我尝试使用来自CFLocale的标识符)。

我的程序需要C ++ std::locale才能格式化日期和数字。

也许我需要在构建中包括其他库?

我正在使用最新的XCode 9.4.1及其随附的libc ++,它可以在iOS 11.4.1上运行。其他C ++功能在此也可以正常工作。

不幸的是,尽管我尝试过的所有语言都在NSLocale.availableLocaleIdentifiers中列出,但无法列出可移植C ++的可用语言环境

1 个答案:

答案 0 :(得分:2)

经过一些研究后,我了解到iOS版本不包含C语言环境。没有。

我的解决方案(因为我想用C ++格式化价格,时间和日期),因此可以在我的应用程序中发布语言环境定义。首先将它们解压缩,然后将PATH_LOCALE环境变量设置为新创建的目录。 (PATH_LOCALE是C库的BSD环境变量,用于定位语言环境定义,而不是GNU / Linux上的LOCPATH)

PATH_LOCALE是语言环境文件的基本路径,每个语言环境都位于子目录中,例如:

fr / LC_TIME fr / .. zh / LC ...

所以我需要子目录,而iOS捆绑软件不支持子目录。

这样做的时候

setlocale(LC_CTYPE,“ en_US.UTF-8”);

C库在PATH_LOCALE中查找名为“ en_US.UTF-8”的目录。

NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

    NSString* localeDir = [documentsPath stringByAppendingPathComponent:@"/locale"];
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:localeDir];

    if (!fileExists) {
        NSString *filepath = [[NSBundle mainBundle] pathForResource:@"locale" ofType:@"zip"];
        ZipArchive *zipArchive = [[ZipArchive alloc] init];
        [zipArchive UnzipOpenFile:filepath];
        [zipArchive UnzipFileTo:documentsPath overWrite:YES];
        [zipArchive UnzipCloseFile];
    }
    setenv("PATH_LOCALE", [[NSString stringWithFormat:@"%@/locale", documentsPath] cString], 1);

这使用了必须包含在项目中的Ziparchive。

https://code.google.com/archive/p/ziparchive/