Обновление № 2: Unicode нельзя использовать в Setfill. Сейчас ищем альтернативы.
Спасибо всем, кто помог!
Обновление: благодаря jkb я понял, что использую указатель. Однако теперь я все еще не понимаю, как поместить юникод в char
, чтобы использовать его в SetFill()
. Это мой новый вопрос.
Оригинальный вопрос:
Я пытаюсь использовать Символ Юникода для моего Setfill(), но я не понимаю, почему это не работает. Setfill() требует Char, а «line» — это Char, который отлично отображается в std::cout. Однако я получаю сообщение об ошибке: «неправильный тип символа для setfill».
char line = u8"\u2501";
cout << setfill(line) << setw(10) << "┛";
// Ошибка: неправильный тип символа для setfill
cout << line << endl;
// Правильно отображает строку
Я искал информацию об использовании Unicode в Setfill, но не нашел ничего близкого к тому, что мне нужно. Я попробовал код выше и сразу вставил символ: Setfill('━')
, но это не сработало.
Я был бы признателен за кивок в правильном направлении, поскольку я застрял.
Заранее спасибо!
изменить: я изменил первую строку кода на основе того, что сказал jkb:
строка не является типом char, это тип char * (указатель). - джкб
раньше было так:
const char* line = u8"\u2501";
u8"\u2501"
— это char8_t[4]
, а не char
, и нет возможности передать ему символ Unicode, потому что кодовые точки > 127 требуют более 1 байта.
Юникод имеет различные форматы. UTF-8 — это формат, который кодирует большинство типичных английских символов одним байтом. Однако для кодирования многих из десятков тысяч символов Unicode требуется более одного байта.
Однако setfill()
адаптируется к потоку, с которым он используется. cout не является потоком широких символов (UTF-16, 16 бит, 2 байта). Значит, выбранный вами персонаж не подходит.
Как указано в другом ответе. Следующий код, вероятно, удовлетворит ваши потребности.
std::wcout << std::setfill(L'\u2501') << std::setw(10) << L'\u251b' << std::endl;
Функция wcout
— это расширенная версия cout
.
Спасибо, что указали, что Setfill нельзя использовать с Unicode. Я все еще новичок в C++, поэтому я подумал, что могу что-то сделать, чтобы заставить его работать или заставить его работать. теперь буду искать альтернативу. Кроме того, я работаю над тем, чтобы это работало на Windows, а не на Linux, извините за это. Я не подумал включить это в свой вопрос.
Исправил мой ответ, основываясь на отличном вкладе Криса Додда.
«16 бит, 2 байта» Это зависит от реализации.
нет таких вещей как "Юникод-8" или "Юникод-16". Юникод — это просто набор символов, т. е. отображение числа (называемого кодовой точкой) в глиф. Это число закодировано различными способами (кодировка), называемая UTF-1, 7, 8, 9, 16, 32...
Существуют ли реализации, использующие cout для UTF-16? Я не знал об этом. У вас есть пример? Я должен признать, что большая часть моего опыта связана с Windows и немного с 8-битными встроенными системами. (Комментарий исправлен для терминологии UTF/Unicode на основе комментария phuclv). Спасибо.
Если вы хотите выводить широкие символы, вам нужно использовать wostream.
std::wcout << std::setfill(L'\u2501') << std::setw(10) << L'\u251b' << std::endl;
должен делать то, что вы хотите.
Одна вещь, которая вам может понадобиться в Linux для правильной настройки локали:
std::setlocale(LC_ALL, "");
вызывается main
, прежде чем пытаться что-либо вывести. Без этого он будет использовать локаль C по умолчанию, которая не поддерживает юникод.
Я попытался использовать это, и ничего из этой строки не появится на консоли для меня по-прежнему. Сейчас я посмотрю wcout
больше, чтобы устранить неполадки. Спасибо, Крис.
Попробуйте std::wcout << _T("Привет, мир\n"); или std::wcout << L"Hello World\n"); в качестве отправной точки.
даже при широком потоке вы не сможете работать с персонажами вне BMP
line
— это не типchar
, это типchar *
(указатель).