如何将std :: string转换为NSString?


97

嗨,我正在尝试将标准std::string转换为,NSString但运气不佳。

我可以从一个成功地转换NSStringstd::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

我在这里想念什么吗?

提前致谢。


4
它必须是一个错字,但您在'NSString * realm =“ Hollywood”;'中缺少字符串文字的'@'。线。
弗拉基米尔

Answers:


111

从std :: string中获取c字符串以进行转换:

NSString *errorMessage = [NSString stringWithCString:REALM.c_str() 
                                   encoding:[NSString defaultCStringEncoding]];

正如文档所述,这似乎不是一个好答案:/ *取决于用户的编码,其值来源于用户的默认语言和其他可能的因素。在没有其他提示的情况下解释未知编码的用户文档时,有时可能需要使用此编码。根本不应该使用这种编码。请注意,此处的一些潜在值可能会导致甚至相当简单的NSString内容发生意外的编码转换-例如,具有双向编码的标点符号。* /
cyrilchampier 2012年

30
[NSString stringWithUTF8String:mystring.c_str()]似乎更合适,因为std :: string更有可能来自您自己的代码,而这可能是UTF8。
cyrilchampier 2012年

你们知道为什么在这里(developer.apple.com/documentation/foundation/nsstring/…)上显示“返回的对象可能与原始接收者不同”的原因吗?这是什么意思,我们怎么知道是否不同?
isJulian00 '19

@cyrilchapier如果我们的.mm文件说“未指定特定编码”怎么办?
isJulian00

53

首先,您必须使用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邮件列表档案

@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编辑),您现在可以:

NSString* result = [NSString stringWithstring:param];
string convertedBack = [result getstring];

和相同std::wstring,这比方便多了。


1
这是rad,我已经在多个iphone项目中使用过它。我注意到的一件事是,如果我正在运行Apple的单元测试框架,并且正在测试使用这些方法的库,则必须将包含字符串转换方法的文件作为“构建阶段”中的“编译源”之一包括在内。单元测试。奇怪的。
大卫,

1
是的,单元测试本质上是它自己的小程序,需要访问相同的代码。此外,对于实际编写测试的荣誉;-)
rvalue 2013年

1
你们知道为什么在这里(developer.apple.com/documentation/foundation/nsstring/…)上显示“返回的对象可能与原始接收者不同”的原因吗?这是什么意思,我们怎么知道是否不同?
isJulian00 '19

1
@izzyMachado文档中的这种语言通常意味着它们在接口协定下保留“权利”以解析,清理或规范化输入字符串。也就是说,它可能不会往返并且仍会比较==,而是它们可以做出的“最接近”或“最佳”表示。在这种情况下,接收者是NSString类实现,并且返回的值不是Objective-C对象,因此它们也可能使用某种标准语言来覆盖它。
rvalue

您是否知道为什么当我们使用initWithUTF8String且字符串包含非utf8字符时仍然有效,它如何仍能使用该字符串(如果是薄荷UTF-8)并在成为NSString后将其打印出来?
isJulian00 '19


14

苹果现在有了一种新的方式,他们希望您执行此转换。在XCode7中,我使用了Edit> Convert> To Modern Objective C Syntax ...选项来找出答案。它使用简写@符号。

std::string sCPPString = "Hello World!";
NSString *sAppleString = @(sCPPString.c_str());

3

我还发现:

NSString *nsString = [NSString stringWithFormat:@"%s",standardString];

像冠军一样工作。


3
这是非常不安全的,并且不能保证能正常工作。如果std :: string是C ++对象,则为standardString。C ++对象不安全地传递给可变参数函数(可变模板在C ++ 11中解决了此问题)。如果工作正常,那是fl幸,几乎每个编译器都至少会警告您不要这样做(如果开始时不是错误)。
维塔利

3

这是代码段/示例:

string str_simple = "HELLO WORLD";

//string to NSString
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str()
                                encoding:[NSString defaultCStringEncoding]];            
NSLog(stringinObjC);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.