2015-05-28 5 views
1

Я хотел распечатать изображения игральных карт с помощью Unicode.Использование sprintf с символами Unicode

Фрагмент кода:

void printCard(int card){ 
    char strCard[10]; 
    sprintf(strCard, "\U0001F0A%x", (card%13)+1); 
    printf("%s\n", cardStr); 
} 

Поскольку \ U требует 8 шестнадцатеричных символов после него я получаю от компиляции:

error: incomplete universal character name \U0001F0A

Я мог бы создать кучу если/другое заявления и распечатал карту таким образом, но я надеялся, что это не заставит меня явно выписать кодировку Unicode каждой карты.

+3

Используйте 'swprintf' и т. Д. И используйте широкие символы. Сохраните источник как uni-код и префиксные строки с помощью L –

+2

Не можете ли вы просто вычислить точку кода как wchar_t? Тем не менее, я был бы удивлен, если printf напечатал это правильно - в какой среде вы находитесь? – Rup

+0

Какую кодировку Unicode вы используете? Современные редакторы используют UTF8. Обратите внимание, что компилятор должен быть соответствующим образом настроен для ввода кодировки и выходной кодировки. Например, gcc использует utf-8, также по умолчанию для обоих. Однако вы можете изменить оба варианта. Для внутренних символов вам понадобится соответствующий тип (не уверен, что 'wchar_t' является правильным для любой кодировки и для char-массивов (vulgo:« strings »)). – Olaf

ответ

3

Универсальные имена символов (например, \U0001F0A1) разрешаются компилятором. Если вы используете один в строке формата, printf увидит представление символа UTF-8; он не знает, как обращаться с обратными слэшами. (То же самое относится к \n и \x2C, это отдельные символы, разрешенные компилятором.) Таким образом, вы, конечно, не можете вычислить UCN во время выполнения.

Наиболее читаемым решением будет использование массива строк для хранения 13 разных карточных символов.

Это позволит избежать знаний о кодировании Unicode и UTF-8 в программе. Если вы знали, что активная локаль является языковой версией UTF-8, вы можете вычислить кодовые точки как wchar_t и использовать стандартные библиотечные функции с широким символом и многобайтом для создания версии UTF-8. Но я совсем не убежден, что это было бы полезно.

1

Быстрый и грязный UTF-8, решение:

void printCard(int card) { 
    printf("\xF0\x9F\x82%c\n", 0xA1 + card % 13); 
} 

UTF-8 представление \U0001F0A1 является F0 9F 82 A1. Вышеупомянутый код будет корректно обрабатывать все 13 карт, если ваш терминал поддерживает UTF-8 и не BMP-коды, например iTerm2 на OS/X.

Альтернативные решения, включающие преобразование широкого символа в многобайтовые наборы символов, сложны в использовании и не будут работать на платформах, где wchar_t ограничен 16 бит.

Смежные вопросы