2010-08-23 45 views
77

Xin chào Tôi đang cố gắng chuyển đổi một tiêu chuẩn std::string thành một số NSString nhưng tôi không có nhiều may mắn.Làm thế nào để chuyển đổi std :: string thành NSString?

tôi có thể chuyển đổi thành công từ một NSString đến một std::string với đoạn mã sau

NSString *realm = @"Hollywood"; 
std::string REALM = [realm cStringUsingEncoding:[NSString defaultCStringEncoding]]; 

Tuy nhiên tôi nhận được một lỗi thời gian biên dịch khi tôi thử như sau

NSString *errorMessage = [NSString stringWithCString:REALM encoding:[NSString defaultCStringEncoding]]; 

Các lỗi tôi nhận được là

Cannot convert 'std::string' to 'const char*' in argument passing 

Tôi có thiếu gì đó ở đây không?

Xin cảm ơn trước.

+4

Nó phải là một lỗi đánh máy, nhưng bạn đang bỏ lỡ '@' cho chuỗi chữ trong 'NSString * vương = "Hollywood";' hàng. – Vladimir

+0

Đã sửa trong chỉnh sửa của tôi. –

Trả lời

88

Nhận c-string ra khỏi std :: string cho chuyển đổi:

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

Điều này dường như không phải là câu trả lời hay, vì tài liệu nói: /* Mã hóa người dùng phụ thuộc vào giá trị được lấy từ ngôn ngữ mặc định của người dùng và các yếu tố khác có khả năng. Việc sử dụng mã hóa này đôi khi có thể cần thiết khi diễn giải tài liệu người dùng bằng mã hóa không xác định, trong trường hợp không có các gợi ý khác. Mã hóa này nên được sử dụng hiếm khi, nếu có. Lưu ý rằng một số giá trị tiềm năng ở đây có thể dẫn đến chuyển đổi mã hóa không mong muốn ngay cả nội dung NSString thậm chí khá đơn giản --- ví dụ: ký tự dấu chấm câu với mã hóa hai chiều. */ – cyrilchampier

+23

[Chuỗi NSStringWithUTF8String: mystring.c_str()] có vẻ phù hợp hơn, vì chuỗi std :: có nhiều khả năng đến từ mã của riêng bạn, có khả năng là UTF8. – cyrilchampier

42

Thứ nhất, bạn đã có được sử dụng Objective-C++ để làm việc này một chút nào; Cách dễ nhất để đảm bảo đó là đổi tên tất cả *.m tập tin của bạn để *.mm

Bởi đến nay có thể sử dụng hầu hết các cách thủ công (không bị phản đối) nhận được một C++ std::string thành một NSString là với:

std::string param; // <-- input 
NSString* result = [NSString stringWithUTF8String:param.c_str()]; 
NSString* alternative = [[NSString alloc] initWithUTF8String:param.c_str()]; 

này sẽ làm việc trong hầu hết các trường hợp - và nếu bạn không thực hiện phát hiện và chuyển đổi mã cụ thể, UTF-8 sẽ cung cấp cho bạn kết quả tốt cho việc có các ký tự không phải là chữ latin ”.

Nếu bạn đang tạo một ứng dụng lớn hơn hoặc bạn không phải là người duy nhất làm việc trên ứng dụng đó, tuy nhiên - có thể bạn sẽ muốn có thứ dễ áp ​​dụng hơn.

Phỏng theo 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 

Với rằng tại chỗ (và thích hợp #import ed), bạn có thể:

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

Và tương tự cho std::wstring, mà là nhiều hơn tiện dụng.

+1

Đây là rad và tôi đã sử dụng nó trong một vài dự án iphone. Một điều tôi nhận thấy là nếu tôi đang chạy thử nghiệm đơn vị của Apple và tôi đã thử nghiệm một thư viện sử dụng các phương pháp này, tôi đã bao gồm tệp chứa các phương thức chuyển đổi chuỗi là một trong các "Biên dịch nguồn" trong "Giai đoạn xây dựng" cho kiểm tra đơn vị. Kỳ dị. – David

+1

Đúng, kiểm tra đơn vị về cơ bản là chương trình nhỏ của riêng nó và cần có quyền truy cập vào cùng một mã. Ngoài ra, kudo để thực sự viết bài kiểm tra ;-) – rvalue

3

Tôi cũng đã phát hiện ra rằng:

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

trình giống như một nhà vô địch.

+3

Đó là khá không an toàn và không được bảo đảm để làm việc. standardString nếu một chuỗi std ::, là một đối tượng C++. Các đối tượng C++ không an toàn khi chuyển sang các hàm variadic (các mẫu variadic giải quyết vấn đề này trong C++ 11). Nếu nó hoạt động đó là một fluke và hầu hết các trình biên dịch sẽ ít nhất cảnh báo bạn chống lại việc này (nếu nó không phải là một lỗi để bắt đầu với). – Vitali

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

Apple hiện có cách mới mà họ muốn bạn thực hiện chuyển đổi này. Trong XCode7, tôi sử dụng tùy chọn Edit> Convert> To Modern Objective C Syntax ... để tìm ra điều này. Nó sử dụng ký hiệu @ viết tắt.

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

Dưới đây là đoạn mã/example:

string str_simple = "HELLO WORLD"; 

//string to NSString 
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str() 
           encoding:[NSString defaultCStringEncoding]];    
NSLog(stringinObjC); 
Các vấn đề liên quan