iOS系统swprintf格式化带中文字符参数串的EILSEQ问题

之前在Android NDK下纠结过wchar的问题,发现在官方文档里写着2.3以上系统支持部分wchar相关函数,如wcslen等,不支持swprintf,mbstowcs等,很是遗憾,只能自己找了相关函数的源码作了替代实现。现在居然发现在iOS上用swprintf效果也是不尽人意。

省略若干google baidu以及排查调试的过程,直接讲结果,就是在用swprintf的时候任何参数串内容带有中文字符(应该是所有非ansi那些),就会导致返回错误-1,查看errno错误号是EILSEQ,原因就是wchar串里有无法解析的编码字符,这个问题的解决方法是:

在调用swprintf前,进行locale设置:setlocale(LC_CTYPE,”UTF-8″),顺带一说,源代码文件的文本编码是UTF-8,setlocale的文档传送:http://www.cplusplus.com/reference/clibrary/clocale/setlocale/,做过这步操作后在simulator上ok了,拼串中的中文不再导致swprintf出错了。本以为问题就这么终结了,结果发现修改后的代码在设备上运行时还是会出现问题,和没改一样。检查了一下是setlocale返回NULL,调用失败,查errno结果是ENOENT,文件未找到?发现https://devforums.apple.com/message/171660#171660,apple开发论坛上有人提到这个,就是设备上的setlocale只有””, “C” & “POSIX”.这几个可用参数,但提了个解决方法,就是自己生成setlocale指定编码所需的数据文件,用mklocale这个工具,我呢,直接到/usr/share/locale下把UTF-8这个夹子给端到自己程序的资源目录里,维持目录结构不变,然后把程序自身资源路径设置给setlocale搜索路径的环境变量,这下就ok了,设备也可以成功执行swprintf了。

NSString* resources = [ [ NSBundle mainBundle ] resourcePath ];      int success = setenv("PATH_LOCALE", [resources cStringUsingEncoding:1], 1); setlocale(LC_CTYPE,"UTF-8"); 调用一次就可以了。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。