std :: stringをNSStringに変換する方法は?


97

こんにちは、私は標準を変換しようとしていますstd::stringNSString、私は多くの幸運を持っていませんよ。

私はから首尾よく変換することができます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";'の文字列リテラルの '@'がありません ライン。
ウラジミール

回答:


111

変換のためにstd :: stringからc-stringを取得します。

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

ドキュメントが言うように、これは良い答えではないようです:/ *ユーザーのデフォルトの言語と潜在的に他の要因から値を取得するユーザー依存のエンコーディング。他のヒントがない場合、未知のエンコーディングでユーザードキュメントを解釈するときに、このエンコーディングの使用が必要になることがあります。このエンコーディングは、使用する場合はめったに使用されません。ここでのいくつかの潜在的な値は、かなり単純なNSStringコンテンツの予期しないエンコーディング変換につながる可能性があることに注意してください-たとえば、双方向エンコーディングの句読文字。* /
cyrilchampier

30
[NSString stringWithUTF8String:mystring.c_str()]は、std :: stringがおそらくUTF8である独自のコードから来る可能性が高いため、より適切に思われます。
cyrilchampier

ここ(developer.apple.com/documentation/foundation/nsstring/…)に「返されたオブジェクトが元のレシーバーと異なる場合がある」と書かれている理由を知っていますか?これはどういう意味ですか?
isJulian00

@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つとして含める必要があったことです。ユニットテスト。変だ。
David

1
うん、単体テストは本質的にそれ自体が小さなプログラムであり、同じコードにアクセスする必要がある。また、実際にテストを作成することに対する称賛;-)
右辺値

1
ここ(developer.apple.com/documentation/foundation/nsstring/…)に「返されたオブジェクトが元のレシーバーと異なる場合がある」と書かれている理由を知っていますか?これはどういう意味ですか?
isJulian00

1
@izzyMachadoは、ドキュメント内のそのような言語は、通常、インターフェイスコントラクトの下で入力文字列を解析、サニタイズ、または正規化する「権利」を予約することを意味します。つまり、往復する==ことなく比較することはできますが、「最も近い」または「最良の」表現のどちらかになります。この場合のレシーバーはNSStringクラスの実装であり、戻り値はObjective-Cオブジェクトではないため、標準言語でそれをカバーしている場合もあります。
右辺値

initWithUTF8Stringを使用していて、文字列にutf8以外の文字が含まれている場合にこれが引き続き機能する理由を知っていますか?それでも、文字列(mint UTF-8の場合)を使用して、NSStringになったときに出力することができますか?
isJulian00

21
NSString* mystring = [NSString stringWithUTF8String:stdstring.c_str()];

これはNSString UTF8を作るのですか?またはNSStringはどのようなエンコーディングになりますか?
isJulian00

14

アップルは今、彼らがあなたにこの変換をすることを望む新しい方法を持っています。XCode7では、[編集]> [変換]> [最新のObjective C構文...]オプションを使用してこれを確認しました。短縮形の@記号を使用しています。

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

3

私もそれを見つけました:

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

チャンピオンのように機能します。


3
これはかなり安全ではなく、動作することが保証されていません。std :: stringの場合、standardStringはC ++オブジェクトです。C ++オブジェクトは、可変個関数に渡すのに安全ではありません(可変テンプレートは、C ++ 11でこの問題を解決します)。それが機能する場合、それはまぐれであり、ほとんどすべてのコンパイラーは少なくともこれを行うことに対して警告します(それが最初からエラーではない場合)。
Vitali 2013年

3

これがコードスニペット/例です。

string str_simple = "HELLO WORLD";

//string to NSString
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str()
                                encoding:[NSString defaultCStringEncoding]];            
NSLog(stringinObjC);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.