xcode ENUM с использованием литерального символа UTF8 - PullRequest
2 голосов
/ 18 февраля 2012

Я прочитал этот связанный вопрос , но он не совсем мне помогает.

Цель Enum - содержать необработанный код UTF-8 (а не кодовую точку Unicode)одиночных символов UTF-8 в диапазоне 4 байта.

Следующий пример работает, потому что исходный файл 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 Ответ

1 голос
/ 08 января 2013

Используйте 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 в макросы, если это необходимо ... но показанный способ является чистым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...