目标c不喜欢我的unichars?

cor*_*ras 8 xcode gcc objective-c

当我尝试执行以下操作时,Xcode对"多字符字符包含"的抱怨:

static unichar accent characters[] = { '?', 'á', '?', 'à' };
Run Code Online (Sandbox Code Playgroud)

如果不是所有字符都是ascii,你如何制作一个字符数组?以下工作正常

static unichar accent[] = { 'a', 'b', 'c' }; 
Run Code Online (Sandbox Code Playgroud)

解决方法

我发现最接近的工作是将特殊字符转换为十六进制,即这有效:

static unichar accent characters[] = { 0x0100, 0x0101, 0x0102 };
Run Code Online (Sandbox Code Playgroud)

Yuj*_*uji 18

并不是说Objective-C不喜欢它,而是C不这样做.常量'c'char1个字节,而不是unichar2个字节.(有关详细信息,请参阅下面的注释.)

没有完美支持的方式来表示unichar常量.您可以使用

char* s="ü";
Run Code Online (Sandbox Code Playgroud)

在UTF-8编码的源文件中获取unicode C-string,或

NSString* s=@"ü";
Run Code Online (Sandbox Code Playgroud)

在UTF-8编码的源文件中获取NSString.(这在10.5之前是不可能的.对iPhone来说没问题.)

NSString本身在概念上是编码中立的; 但如果你愿意,你可以通过使用获得unicode字符-characterAtIndex:.

最后两条评论:

  • 如果你只想从字符串中删除重音,你可以使用这样的方法,而无需自己编写表:

    -(NSString*)stringWithoutAccentsFromString:(NSString*)s
    {
        if (!s) return nil;
        NSMutableString *result = [NSMutableString stringWithString:s];
        CFStringFold((CFMutableStringRef)result, kCFCompareDiacriticInsensitive, NULL);
        return result;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    请参阅CFStringFold的文档.

  • 如果您想要unicode字符进行本地化/国际化,则不应将字符串嵌入源代码中.相反,你应该使用Localizable.stringsNSLocalizedString.看到这里.

注意:神秘历史的原因,'a'int在C,看到的讨论在这里.在C++中,它是一个char.但它并没有改变这样一个事实,即在内部写入多个字节'...'是实现定义的,不推荐使用.例如,参见ISO C标准6.4.4.10.但是,在经典的Mac OS中编写用单引号括起来的四字母代码很常见'APPL'.但那是另一个故事......

另一个复杂因素是重音字母并不总是由1个字节表示; 这取决于编码.在UTF-8中,它不是.在ISO-8859-1中,它是.并且unichar应该是UTF-16.您是否以UTF-16保存了源代码?我认为XCode的默认值是UTF-8.GCC可能会根据设置进行一些编码转换......


dan*_*ndi 7

或者你可以这样做:

static unichar accent characters[] = { L'?', L'á', L'?', L'à' };
Run Code Online (Sandbox Code Playgroud)

L是标准的C关键字,表示"我即将编写UNICODE字符或字符集".

也适用于Objective-C.

注意:编译器可能会向你发出一个奇怪的警告,说明在unichar中放置了太多字符,但你可以放心地忽略该警告.Xcode只是没有以正确的方式处理unicode字符,但是编译器正确地解析它们并且结果是正常的.