将具有重音字符的NSString转换为CString

我有一个NSString的价值何塞(在e的重音)。 我尝试将其转换为Cstring,如下所示:

char str [[myAccentStr length] + 1]; [myAccentStr getCString:str maxLength:[myAccentStr length] + 1 encoding:NSUTF32StringEncoding]; 

但str最终是一个空string。 是什么赋予了? 我也试过UTF8和UTF16。 它会在稍后被传递给另一个函数,当funcsion调用它时,尺寸会变成零。

NSString getCString:maxLength:encoding的文档说:

你可以使用canBeConvertedToEncoding:来检查一个string是否可以被无损转换为编码。 如果不行,可以使用dataUsingEncoding:allowLossyConversion:使用编码来获取Cstring表示,从而允许信息丢失(请注意,由dataUsingEncoding:allowLossyConversion返回的数据不是一个严格的Cstring,因为它没有有一个NULL结束符)。

使用NSString方法dataUsingEncoding:allowLossyConversion:做的伎俩。 这是一个代码示例:

 NSString *myAccentStr = @"José"; char str[[myAccentStr length] + 1]; // NSString * to C String (char*) NSData *strData = [myAccentStr dataUsingEncoding:NSMacOSRomanStringEncoding allowLossyConversion:YES]; memcpy(str, [strData bytes], [strData length] + 1); str[[myAccentStr length]] = '\0'; NSLog(@"str (from NSString* to c string): %s", str); // C String (char*) to NSString * NSString *newAccentStr = [NSString stringWithCString:str encoding:NSMacOSRomanStringEncoding]; NSLog(@"newAccentStr (from c string to NSString*): %@", newAccentStr); 

该NSLog的输出是:

str(从NSString *到Cstring):José

newAccentStr(从Cstring到NSString *):José

到目前为止,我只在使用NSMacOSRomanStringEncoding时才看到这个工作正常。


编辑

将其更改为社区wiki。 请随意编辑。

hooleyhoop有一些伟大的观点,所以我想我会尽可能使代码尽可能冗长。 如果我错过了什么,请别人请进。

另外 – 不知道为什么[NSString canBeConvertedToEncoding:]返回YES,即使[NSString getCString:maxLength:encoding:]函数肯定不能正常工作(如输出所示)。

这里有一些代码可以帮助分析什么可行/什么不行:

 // Define Block variable to tests out different encodings void (^tryGetCStringUsingEncoding)(NSString*, NSStringEncoding) = ^(NSString* originalNSString, NSStringEncoding encoding) { NSLog(@"Trying to convert \"%@\" using encoding: 0x%X", originalNSString, encoding); BOOL canEncode = [originalNSString canBeConvertedToEncoding:encoding]; if (!canEncode) { NSLog(@" Can not encode \"%@\" using encoding %X", originalNSString, encoding); } else { // Try encoding using NSString getCString:maxLength:encoding: NSUInteger cStrLength = [originalNSString lengthOfBytesUsingEncoding:encoding]; char cstr[cStrLength]; [originalNSString getCString:cstr maxLength:cStrLength encoding:encoding]; NSLog(@" Converted(1): \"%s\" (expected length: %u)", cstr, cStrLength); // Try encoding using NSString dataUsingEncoding:allowLossyConversion: NSData *strData = [originalNSString dataUsingEncoding:encoding allowLossyConversion:YES]; char cstr2[[strData length] + 1]; memcpy(cstr2, [strData bytes], [strData length] + 1); cstr2[[strData length]] = '\0'; NSLog(@" Converted(2): \"%s\" (expected length: %u)", cstr2, [strData length]); } }; NSString *myAccentStr = @"José"; // Try out whatever encoding you want tryGetCStringUsingEncoding(myAccentStr, NSUTF8StringEncoding); tryGetCStringUsingEncoding(myAccentStr, NSUTF16StringEncoding); tryGetCStringUsingEncoding(myAccentStr, NSUTF32StringEncoding); tryGetCStringUsingEncoding(myAccentStr, NSMacOSRomanStringEncoding); 

结果:

 > Trying to convert "José" using encoding: 0x4 > Converted(1): "" (expected length: 5) > Converted(2): "Jos√©" (expected length: 5) > Trying to convert "José" using encoding: 0xA > Converted(1): "" (expected length: 8) > Converted(2): "ˇ˛J" (expected length: 10) > Trying to convert "José" using encoding: 0x8C000100 > Converted(1): "" (expected length: 16) > Converted(2): "ˇ˛" (expected length: 20) > Trying to convert "José" using encoding: 0x1E > Converted(1): "-" (expected length: 4) > Converted(2): "José" (expected length: 4) 

[aString length]返回字符数。 在你的情况下,这是4

您可以使用例如NSUTF8StringEncodingNSUTF16StringEncodingNSUTF32StringEncoding将string准确地转换为ACstring。 字节长度分别为5,8,16。

 NSString *myAccentStr = @"José"; NSUInteger l1 = [myAccentStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; NSUInteger l2 = [myAccentStr lengthOfBytesUsingEncoding:NSUTF16StringEncoding]; NSUInteger l3 = [myAccentStr lengthOfBytesUsingEncoding:NSUTF32StringEncoding]; NSLog(@"%ld %ld %ld", (long)l1, (long)l2, (long)l3); > 5, 8, 16 

为了进行转换,您应该使用-lengthOfBytesUsingEncoding代替-lengthOfBytesUsingEncoding

始终使用-canBeConvertedToEncoding检查转换是否有效

有很好的理由使用NSString