You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:10:31