Я использую Ncurses для написания текстового редактора. Я хотел бы знать, есть ли способ определить, сколько разных символов можно разместить на экране, где каждый символ закодирован с помощью UTF-8. Например, когда я получаю ширину экрана 10 и одну строку, я могу поместить 10 символов ширины 1 со значениями, как показано ниже:
0123456789
Но когда я хочу разместить целый ряд улыбающихся лиц, я могу разместить только 4 из них на экране размером 10:
????
Так что в этом примере улыбающееся лицо занимает на экране ширину 2,5. Я хотел бы знать, есть ли способ определить ширину символа на экране?
связанные: std::setw и символ Юникода





ncurses использует wcwidth для определения количества столбцов, которые использует «расширенный символ» (обычно значение Unicode) в wchar_t. Это может не совпадать с тем, что на самом деле делает терминал, но если ваша локаль (LC_CTYPE и т. д.) установлена в соответствии с возможностями и конфигурацией терминала, результаты будут достаточно согласованными.
Хотя wcwidth — стандартная функция, она не полностью стандартизирована (могу отвлечься). В большинстве реализаций используются таблицы, которые периодически обновляются (один из источников проблем), эмуляторы терминала могут/могут не соответствовать друг другу, а шрифты может не соответствовать значениям в wcwidth.
Имея все это в виду, вы всегда можете спросить ncurses (или любую другую реализацию X/Open Curses), сколько столбцов на экране он будет использовать, записывая в окно, которое вы не отображаете. Lynx делает это, например, в LYStrExtent0:
/*
* Determine the number of cells the given string would take up on the screen,
* limited (in the case of wide characters) by the maxCells parameter.
*
* If the returnCellNum parameter is TRUE, return the number of cells;
* otherwise, return the length (limited by the len parameter) of the prefix of
* the string that fits in maxCells cells.
*/
разве это не определяется шрифтом, который вы используете? только если каждый символ имеет одинаковую ширину, вы можете заранее узнать, насколько широким будет определенное количество символов.