使用NSString initWithFormat打印中文乱码,iOS中如何解决?
iOS中C++ std::string中文插入NSString乱码的解决方法
问题原因
NSString的initWithFormat方法里,%s格式符会按照**系统默认单字节编码(如ASCII、ISO-8859-1)**解析传入的C字符串。而你的std::string存储的中文是UTF-8编码的多字节字符,用单字节编码解析多字节UTF-8必然会出现乱码。
直接场景的解决方法
不要用%s格式符,先将std::string转换为UTF-8编码的NSString,再用%@格式符插入:
std::string title = "中文"; NSString* titleStr = [[NSString alloc] initWithUTF8String:title.c_str()]; NSString* str = [[NSString alloc] initWithFormat:@"test 中文 %@", titleStr];
%@是NSString专属的格式符,能正确处理Unicode字符,避免乱码。
nativeLog函数的修复方案
你的nativeLog函数乱码的核心问题和直接场景一致:用%s传递UTF-8中文时,initWithFormat无法正确解码。以下是两种可行的修复方式:
方案1:修改调用时的格式符与参数类型
调用nativeLog时,先把std::string转成NSString,用%@格式符传递参数:
std::string title = "中文"; nativeLog("test 中文 %@", [[NSString alloc] initWithUTF8String:title.c_str()]);
注:你当前代码中用initWithUTF8String:处理格式字符串的逻辑是正确的,能保证格式字符串本身的中文正常显示。
方案2:优化nativeLog函数(兼容原有调用逻辑)
如果不想修改调用方式,可以调整函数内部逻辑,自动将UTF-8编码的C字符串参数转为NSString。示例如下:
void nativeLog2(NSString* format, va_list args) { NSString* str = [[NSString alloc] initWithFormat:format arguments:args]; NSLog(str); } void nativeLog(const char* format, ...) { va_list args; va_start(args, format); NSString* nsFormat = [[NSString alloc] initWithUTF8String:format]; nativeLog2(nsFormat, args); va_end(args); } // 调用示例(需将std::string转NSString后用%@传递) std::string title = "中文"; nativeLog("test 中文 %@", [[NSString alloc] initWithUTF8String:title.c_str()]);
关键总结
%s仅适用于单字节编码的字符串,完全不适合处理UTF-8多字节中文;- C++与OC字符串交互时,必须保证编码统一为UTF-8,且通过
initWithUTF8String:完成std::string到NSString的转换; - 格式化NSString时,用
%@处理NSString类型参数是最稳妥的方式。
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

