【问题标题】:Xcode UTF-8 literalsXcode UTF-8 文字
【发布时间】:2011-08-07 02:31:25
【问题描述】:

假设我有MUSICAL SYMBOL G CLEF 符号:** ???? ** 我希望在我的 Objective-C 源文件中包含一个字符串文字。

OS X 字符查看器显示 CLEF 是 UTF8 F0 9D 84 9E 和 Unicode 1D11E(D834+DD1E)

经过一番折腾,并使用 the ICU UNICODE Demonstration Page,我确实得到了以下代码:

NSString *uni=@"\U0001d11e";
NSString *uni2=[[NSString alloc] initWithUTF8String:"\xF0\x9D\x84\x9E"];
NSString *uni3=@"????";
NSLog(@"unicode: %@ and %@ and %@",uni, uni2, uni3);

我的问题:

  1. 是否可以简化我处理 UTF-8 文字的方式?这对我来说似乎很笨拙。
  2. @"\U0001d11e 部分是 UTF-32 吗?
  3. 为什么从 Character Viewer 剪切和粘贴 CLEF 确实有效?我认为Objective-C文件必须是UTF-8?

【问题讨论】:

  • 您的第一个解决方案让我很开心。谢谢提问! :D
  • 这个问题有 4k 次浏览,但只有 7 次赞成!我确定你不是唯一一个你保存的人:)
  • 适用于 NSLog 但不适用于 UILabel。我得到一个“NA”。

标签: objective-c xcode unicode


【解决方案1】:
  1. 我更喜欢你在uni3 中的做法,但遗憾的是not recommended。如果做不到这一点,我更喜欢uni 中的方法而不是uni2 中的方法。另一种选择是[NSString stringWithFormat:@"%C", 0x1d11e]
  2. 它是一个“通用字符名称”,在 C99(第 6.4.3 节)中引入,并从 OS X 10.5 开始导入到 Objective-C。从技术上讲,这不必为您提供 UTF-8(取决于编译器),但实际上您可能会得到 UTF-8。
  3. 源代码文件的编码可能是 UTF-8,符合运行时的预期,因此一切正常。源文件也可能是 UTF-16 或 UTF-32 并且编译器在编译它时正在做正确的事情。尽管如此,Apple 并不推荐这样做。

【讨论】:

  • %C 仅支持 16 位 Unicode 字符,因此无法处理 0x1d11e。
【解决方案2】:

回答您的问题(顺序相同):

  1. 为什么选择? Xcode 在默认设置中使用 C99。有关通用字符名称,请参阅 the C0X draft specification 6.4.3。见下文。

  2. 从技术上讲,@"\U0001d11eISO 10646 character set 中该字符的 32 位 Unicode 代码点。

  3. 我不会指望这种行为有效。您绝对应该毫无疑问地让源文件中的所有字符都是 7 位 ASCII。对于字符串文字,请使用编码,或者最好使用能够处理二进制数据的合适外部资源。

通用字符名称(来自WG14/N1256 C0X 草案,CLANG 很好地遵循了该草案):

可以使用通用字符名称 在标识符中,字符常量, 和 字符串字面量 来指定 不在基本的字符 字符集。

万能的 角色名 \Unnnnnnnn 指定 八位数短的字符 标识符(由 ISO/IEC 指定 10646) 是 nnnnnnnn) 同样, 通用字符名称 \unnnn 指定其角色 四位短标识符为 nnnn (以及它的八位数短 标识符是 0000nnnn)。

因此,您可以以自然、混合的方式生成字符或字符串:

char *utf8CStr = 
   "May all your CLEF's \xF0\x9D\x84\x9E be left like this: \U0001d11e";
NSString *uni4=[[NSString alloc] initWithUTF8String:utf8CStr];

\Unnnnnnnn 表单允许您选择任何 Unicode 代码点,这与字符查看器左下角的“Unicode”字段的值相同。 C99 源文件中\Unnnnnnnn 的直接条目由编译器适当处理。请注意,只有两个选项:\unnnn,它是默认代码页的 256 个字符偏移量或\Unnnnnnnn,它是任何 Unicode 代码点的完整 32 位字符。如果您不使用全部 4 位或全部 8 位数字或 \u 或 \U,则需要在左侧填充 0。

\xF0\x9D\x84\x9E 在同一字符串文字中的形式更有趣。这是插入相同字符的原始 UTF-8 编码。一旦传递给 initWithUTF8String 方法,但文字和编码文字最终以编码的 UTF-8 结尾。

It may,可以说,以这种方式使用原始字节违反了130 of section 5.1.1.2。鉴于原始 UTF-8 字符串的编码方式类似,我认为您没问题。

【讨论】:

  • 以这种方式使用原始字节肯定不违反第 5.1.1.2 节的 130。 “token concatenation”是指 ## 运算符用于将预处理器中的标记粘贴在一起,用于将 \u1234 之类的东西粘贴在一起以获得 \u1234,这与使用的字符串文字中的字节无关表示一个 UTF-8 字符。
  • 我说,>> 我
  • 一个字符串中的多个编码无疑会搞砸自动检测器编码检测器。 YMMV。
  • 风格很差,当然。安全风险,也许。不过,与第 5.1.1.2 节的 130 无关。
【解决方案3】:
  1. 您也可以在字符串文字中写入谱号:

    NSString *uni2=[[NSString alloc] initWithUTF8String:"?"];
    
  2. \U0001d11e 匹配 G 谱号字符的 unicode 代码点。字符的 UTF-32 形式与其代码点相同,因此如果您愿意,可以将其视为 UTF-32。这是unicode tables for musical symbols的链接。

  3. 您的文件可能是 UTF-8。 G 谱号是一个有效的 UTF8 字符 - 查看 hexdump 的输出以获取您的文件:

    00  4e 53 53 74 72 69 6e 67  20 2a 75 6e 69 33 3d 40  |NSString *uni3=@|
    10  22 f0 9d 84 9e 22 3b 0a  20 20 4e 53 4c 6f 67 28  |"....";.  NSLog(|
    

    如您所见,该字符的正确 UTF-8 表示在您期望的文件中。使用其他方法之一并尝试将源文件保持在 ASCII 范围内可能更安全。

【讨论】:

    【解决方案4】:

    我创建了一些实用程序类,以便在 unicode 代码点、UTF-8 字节序列和 NSString 之间轻松转换。你可以在 Github 上找到code,也许它对某人有些用处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      相关资源
      最近更新 更多