如何将 std::string 转换为 NSString?
Posted
技术标签:
【中文标题】如何将 std::string 转换为 NSString?【英文标题】:How to convert std::string to NSString? 【发布时间】:2011-04-02 21:43:22 【问题描述】:您好,我正在尝试将标准 std::string
转换为 NSString
,但运气不佳。
我可以使用以下代码从NSString
成功转换为std::string
NSString *realm = @"Hollywood";
std::string REALM = [realm cStringUsingEncoding:[NSString defaultCStringEncoding]];
但是当我尝试以下操作时出现编译时错误
NSString *errorMessage = [NSString stringWithCString:REALM encoding:[NSString defaultCStringEncoding]];
我得到的错误是
Cannot convert 'std::string' to 'const char*' in argument passing
我错过了什么吗?
提前致谢。
【问题讨论】:
这一定是一个错字,但你在 'NSString *realm = "Hollywood";' 中缺少字符串文字的 '@'行。 【参考方案1】:从 std::string 中获取 c-string 进行转换:
NSString *errorMessage = [NSString stringWithCString:REALM.c_str()
encoding:[NSString defaultCStringEncoding]];
【讨论】:
这似乎不是一个好的答案,正如文档所说:/* 用户相关编码,其值来自用户的默认语言和可能的其他因素。在没有其他提示的情况下,在解释具有未知编码的用户文档时,有时可能需要使用这种编码。这种编码应该很少使用,如果有的话。请注意,这里的一些潜在值可能会导致甚至相当简单的 NSString 内容的意外编码转换——例如,具有双向编码的标点符号。 */ [NSString stringWithUTF8String:mystring.c_str()] 似乎更合适,因为 std::string 更有可能来自您自己的代码,这很可能在 UTF8 中。 你们知道为什么在这里 (developer.apple.com/documentation/foundation/nsstring/…) 它说“返回的对象可能与原始接收者不同”吗?这是什么意思,我们怎么知道它是否不同? @cyrilchapier 如果我们的 .mm 文件显示“未指定特定编码”怎么办?【参考方案2】:首先,你必须使用 Objective-C++ 才能让它工作。确保这一点的最简单方法是将所有 *.m
文件重命名为 *.mm
到目前为止,将 C++ std::string
转换为 NSString
的最有用(非弃用)手动方法是:
std::string param; // <-- input
NSString* result = [NSString stringWithUTF8String:param.c_str()];
NSString* alternative = [[NSString alloc] initWithUTF8String:param.c_str()];
这在大多数情况下都有效 - 如果您不进行特定的编码检测和转换,UTF-8 将为您提供一个很好的结果,让非拉丁字符“正常工作”。
但是,如果您正在制作一个更大的应用程序,或者您不是唯一一个在开发该应用程序的人,那么您可能会想要更容易应用的东西。
改编自cocoa-dev mailing list archives
@interface NSString (cppstring_additions)
+(NSString*) stringWithwstring:(const std::wstring&)string;
+(NSString*) stringWithstring:(const std::string&)string;
-(std::wstring) getwstring;
-(std::string) getstring;
@end
@implementation NSString (cppstring_additions)
#if TARGET_RT_BIG_ENDIAN
const NSStringEncoding kEncoding_wchar_t = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32BE);
#else
const NSStringEncoding kEncoding_wchar_t = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE);
#endif
+(NSString*) stringWithwstring:(const std::wstring&)ws
char* data = (char*)ws.data();
unsigned size = ws.size() * sizeof(wchar_t);
NSString* result = [[NSString alloc] initWithBytes:data length:size encoding:kEncoding_wchar_t];
return result;
+(NSString*) stringWithstring:(const std::string&)s
NSString* result = [[NSString alloc] initWithUTF8String:s.c_str()];
return result;
-(std::wstring) getwstring
NSData* asData = [self dataUsingEncoding:kEncoding_wchar_t];
return std::wstring((wchar_t*)[asData bytes], [asData length] / sizeof(wchar_t));
-(std::string) getstring
return [self UTF8String];
@end
有了这个就地(并且适当地#import
ed),您现在可以:
NSString* result = [NSString stringWithstring:param];
string convertedBack = [result getstring];
std::wstring
也一样,非常方便。
【讨论】:
这是 rad,我在几个 iphone 项目中使用过它。我注意到的一件事是,如果我正在运行 Apple 的单元测试框架并且我正在测试一个利用这些方法的库,我必须将包含字符串转换方法的文件作为“编译源”之一包含在“构建阶段”中单元测试。很奇怪。 是的,单元测试本质上是它自己的小程序,并且需要访问相同的代码。此外,实际编写测试的荣誉;-) 你们知道为什么在这里 (developer.apple.com/documentation/foundation/nsstring/…) 它说“返回的对象可能与原始接收者不同”吗?这是什么意思,我们怎么知道它是否不同? @izzyMachado 文档中的这种语言通常意味着他们保留接口合同下的“权利”来解析、清理或规范化输入字符串。即它可能不是往返并且仍然比较==
,而是他们可以做出的“最接近”或“最好”的表示。在这种情况下,接收者是 NSString
类实现,并且返回的值不是 Objective-C 对象,所以他们也可能用一些标准语言来覆盖它。
你知道为什么当我们使用 initWithUTF8String 并且字符串包含非 utf8 字符时这仍然有效吗,它如何仍然能够使用字符串(如果它是薄荷 UTF-8)并打印出来一次成为一个 NSString ?【参考方案3】:
NSString* mystring = [NSString stringWithUTF8String:stdstring.c_str()];
【讨论】:
这会使 NSString UTF8 吗?或者 NSString 是什么编码?【参考方案4】:Apple 现在有了一种新的方式,他们希望您进行这种转换。在 XCode7 中,我使用 Edit > Convert > To Modern Objective C Syntax... 选项来找出答案。它使用简写@符号。
std::string sCPPString = "Hello World!";
NSString *sAppleString = @(sCPPString.c_str());
【讨论】:
对不起,如果这是一个愚蠢的问题,但可以肯定的是,是否保证将 sCPPString.c_str() 复制到 sAppleString 中?我的意思是,如果 sCPPString 得分不够,那么 sAppleString 内的内存仍然有效吗?还有一个关于方法 stringWithUTF8String 和 stringWithCString 的问题,第一个是否复制,另一个只是指内存缓冲区,或者两者都保证复制? (我知道第一个复制,但另一个呢),我只是想确定一下。谢谢...【参考方案5】:我还发现:
NSString *nsString = [NSString stringWithFormat:@"%s",standardString];
像冠军一样工作。
【讨论】:
这很不安全,也不能保证能正常工作。如果 std::string,standardString 是 C++ 对象。 C++ 对象对于传递给可变参数函数是不安全的(可变参数模板在 C++11 中解决了这个问题)。如果它有效,那是侥幸,几乎每个编译器都会至少警告你不要这样做(如果它不是一个错误开始的话)。【参考方案6】:这里是代码sn-p/example:
string str_simple = "HELLO WORLD";
//string to NSString
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str()
encoding:[NSString defaultCStringEncoding]];
NSLog(stringinObjC);
【讨论】:
以上是关于如何将 std::string 转换为 NSString?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UTF-8 std::string 转换为 UTF-16 std::wstring?
如何将 System::String^ 转换为 std::string?