2012-02-17 93 views
2

我已閱讀此related question,但它不完全幫助我。使用UTF8文字字符xcode ENUM

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 
}; 

謝謝;

+0

嘗試在枚舉中包含特定的多字節序列是一個壞主意。至少,你會有endian問題 – 2012-02-17 23:33:53

+0

已經考慮到了字節順序,所以這不會是一個問題。 – 2012-02-18 02:30:25

回答

1

使用C++ 11 constexpr和U8前綴,網HRS歐洲http://liveworkspace.org/code/3EtxVE:其輸出

2c 
c2a7 
e29c93 
f09d8da5

#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; 
} 

如果您沒有訪問U8前綴,你可以簡單地保證源文件以UTF-8編碼,我想如果需要的話可以將constexpr變成宏,但是顯示的是一個乾淨的方法。