1

更新:奇怪的是,setlocale() 只在 iOS 模拟器上失败,所以我修改了问题标题。它在实际设备上运行良好。

我正在使用 iOS 6 下的本机 (C/C++) 代码,我需要格式化任意wchar_t字符串。但是,当格式化包含 Latin-1 代码页之外的代码点的字符串时,会swprintf失败(返回值 -1 和 errno= EILSEQ)。

wchar_t buff[256];
swprintf(buff, 256, L"\u00A9 %ls", L"ascii"); // works
swprintf(buff, 256, L"\u03A0 %ls", L"ascii"); // will return -1

在此处询问相关问题后,问题似乎是语言环境设置不正确(我已验证该解决方案在 Mac OS X 下有效)。但是在iOS 6下好像没有效果:

#include <locale.h>

setlocale(LC_CTYPE,"");

按照此处的说明,我已将语言环境文件手动复制/添加到我的项目中,并设置PATH_LOCALE环境变量,但问题仍然存在:

NSString* resourcePath=[[NSBundle mainBundle] resourcePath];
setenv("PATH_LOCALE", [resourcePath UTF8String], 1);
setlocale(LC_CTYPE,"en_US.UTF-8");

有谁知道我如何让 setlocale() 在 iOS 6 下工作(同时仍然让应用程序被 Apple Store 接受)?

4

2 回答 2

1

我无法让斯蒂芬的解决方案发挥作用。但是这两个超级简单的解决方案都对我有用:

  1. setlocale(LC_CTYPE, "UTF-8")
  2. newlocale(LC_CTYPE_MASK, "UTF-8")结合带有语言环境参数的 foo_l 变体 wchar_t 类。

虽然 iOS 可能没有附带一整套语言环境(包括 en_US.UTF-8),但它似乎附带了基本的无语言 UTF-8 语言环境。但它只适用于 LC_CTYPE;尝试 LC_ALL 将失败。你当然可以用

char *result = setlocale(LC_TYPE, "UTF-8");
Assert(result && strcmp(result, "UTF-8") == 0);
于 2019-06-20T23:33:45.803 回答
0

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

fr/LC_TIME fr/.. en/LC...

所以你需要子目录,而 iOS 包不支持子目录。

当你这样做

setlocale(LC_CTYPE,"en_US.UTF-8");

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

我找到的解决方案是将包中的语言环境作为 zip 添加(具有整个子目录结构),在文档路径中首次启动时将其解压缩并将 PATH_LOCALE 设置为该新目录。

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/

于 2018-12-19T22:56:26.387 回答