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

109

我有一个NSString对象,想将其转换为std::string

在Objective-C++中应该如何做?


重复问题:https://dev59.com/AHA65IYBdhLWcg3w7Tea - rvalue
5
@rvalue 不是重复的 - 相反的转换。 - eric
3个回答

155
NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String]);

编辑:几年之后,让我扩展一下这个答案。正如指出的那样,如果您最终要使用std :: string,则通常会希望使用cStringUsingEncoding:NSASCIIStringEncoding 一起使用。您可以在普通的std :: strings中使用UTF-8,但请注意,这些操作是基于字节而不是字符或甚至图形符号的。对于一个很好的“入门”,请查看这个问题及其答案

还要注意,如果您有一个无法表示为ASCII的字符串,但仍然希望以std :: string的形式使用它,并且您不希望其中包含非ASCII字符,那么可以使用dataUsingEncoding:allowLossyConversion:来获取具有有损编码ASCII内容的字符串的NSData表示,然后将其传递给std :: string


14
小心编码。虽然UTF-8通常是一个很好的选择,但如果你正在使用的API期望纯ASCII或系统代码页,则必须使用"-cStringUsingEncoding:"代替。 :) 请注意编码方式。尽管UTF-8通常是一个不错的选择,但如果你所使用的API需要纯ASCII或者系统代码页,那么你就需要使用"-cStringUsingEncoding:"代替。 :) - Jonathan Grynspan
13
如果您不删除它,返回的指针并不是Objective-C引用计数对象,这就是一个内存泄漏。一般来说,您应该避免使用operator new来创建std::string。 - SiimKallas
@JBL 在仅仅4年和几周之后,我又回来扩展我的答案。希望现在更加可接受了。 - JustSid
@JBL 哇,感谢您指出这一点。原始答案使用了指针,一年前更改为非指针答案,但显然被回滚了。我会再次编辑掉指针,抱歉。好的一面是,我终于有证据表明我在SO上提供了人们盲目复制粘贴的错误建议,我感到很荣幸:p - JustSid
@JustSid 这正是我想要指出的原因之一:由于有些人只是盲目地复制粘贴,这会极大地激励我们尽可能正确地回答问题... :P - JBL
显示剩余2条评论

50

如评论中 Ynau 建议的那样,在一般情况下,最好将所有内容保持在堆栈上而不是堆上(使用new会将字符串创建在堆上),因此(假设采用 UTF8 编码):

NSString *foo = @"Foo";
std::string bar([foo UTF8String]);

12

如在philjordan.eu上所提到的,NSString也可能是nil。在这种情况下,类型转换应该像这样进行:

// 注意:如果foo是nil,这将产生一个空的C ++字符串

// 而不是从UTF8String解除引用NULL指针。

这将导致你做出这样的转换:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);

2
这非常有用。令人担忧的是几乎每个人都忽略了它。你们都会在NIL上崩溃。 - P i
这绝对是一个更好的答案。顺便说一下,如果你已经有了一个字符串,就没有必要再为std::string调用一个构造函数和析构函数了。只需执行:strYouHave.assign([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) - c00000fd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接