使用UTF8文字字符的xcode ENUM

时间:2012-02-17 23:16:44

标签: xcode utf-8 enums literals

我已阅读此related question,但它对我没有帮助。

Enum的目标是在4字节范围内包含单个UTF-8字符的原始UTF-8代码(不是unicode代码点)。

以下示例有效,因为xcode源文件采用UTF-8格式(这是xcode的推荐编码)。它使用正确的预期值进行编译和运行。 但是对于这种类型的,我也会得到警告“字符常量太长。我可以抑制它吗?或者坏主意?

typedef enum {
    TEST_VAL_1BYTE = ',', // 0x2C
    TEST_VAL_2BYTE = '§', // 0xC2A7     (the warning)
    TEST_VAL_3BYTE = '✓', // 0xE29C93   (the warning)
    TEST_VAL_4BYTE = '', // 0xF09D8DA5 (the warning)
} TEST_VALUES_UTF8;

最安全的方式,没有警告,但编码更加繁琐:

typedef enum {
    NUM_VAL_1BYTE = 0x2C,       // ,
    NUM_VAL_2BYTE = 0xC2A7,     // §
    NUM_VAL_3BYTE = 0xE29C93,   // ✓
    NUM_VAL_4BYTE = 0xF09D8DA5, // 
} TEST_VALUES_UTF8;

最后请注意,使用1或4个ASCII字符的枚举是有效的,没有警告:

enum {
    ENUM_TEST_1     = '1',     // 0x31        (no warning)
    ENUM_TEST_12    = '12',    // 0x3132      (w: multi-character character constant)
    ENUM_TEST_123   = '123',   // 0x313233    (w: multi-character character constant)
    ENUM_TEST_1234  = '1234',  // 0x31323334  (no warning)
};

是否存在可以返回UTF-8代码的源编码通用的预处理器宏:

enum {
    TEST_VAL_2BYTE = AWESOME_UTF8CODE_MACRO('§'), // 0xC2A7
};

感谢;

1 个答案:

答案 0 :(得分:1)

使用C ++ 11 constexpr和u8前缀,a'la http://liveworkspace.org/code/3EtxVE

#include <iostream>
#include <cstdint>

constexpr uint32_t utf8(const char (&c)[2]) {
   return uint8_t(c[0]);
}
constexpr uint32_t utf8(const char (&c)[3]) {
   return uint8_t(c[1]) | (uint8_t(c[0])<<8);
}
constexpr uint32_t utf8(const char (&c)[4]) {
   return uint8_t(c[2]) | (uint8_t(c[1])<<8) | (uint8_t(c[0])<<16);
}
constexpr uint32_t utf8(const char (&c)[5]) {
   return uint8_t(c[3]) | (uint8_t(c[2])<<8) | (uint8_t(c[1])<<16) | (uint8_t(c[0])<<24);
}

typedef enum {
    TEST_VAL_1BYTE = utf8(u8","),
    TEST_VAL_2BYTE = utf8(u8"§"),
    TEST_VAL_3BYTE = utf8(u8"✓"),
    TEST_VAL_4BYTE = utf8(u8""),
} TEST_VALUES_UTF8;

int main() {
   std::cout << std::hex << TEST_VAL_1BYTE << std::endl;
   std::cout << std::hex << TEST_VAL_2BYTE << std::endl;
   std::cout << std::hex << TEST_VAL_3BYTE << std::endl;
   std::cout << std::hex << TEST_VAL_4BYTE << std::endl;
}

输出

2c
c2a7
e29c93
f09d8da5

如果您无法访问u8前缀,您可以简单地确保源文件以UTF-8编码,我猜您可以根据需要将constexpr转换为宏...但显示的是一种干净的方式。 / p>