Не удается корректно печатать расширенные символы ASCII в NCURSES


У меня есть такая программа:

#include <ncurses.h>
int main () {
    initscr();
    mvaddstr(0, 0, "              A         B         C         D         E       ");
    mvaddstr(1, 24, "ñandñ");
    mvaddstr(1, 34, "esdrñjulñ");
    refresh();
    getch();
    endwin();
    return 0;
}

Когда ncurses печатает первое слово (- и -), что-то происходит, что при последующем перемещении в другую позицию (в данном случае в 1, 34), фактически оно перемещается в другую позицию, поэтому второе слово печатается в другом столбце.

Итак, как это должно выглядеть:

          A         B         C         D         E       
                              ñandñ     esdrñjulñ

Выглядит так:

          A         B         C         D         E       
                              ñandñ   esdrñjulñ

Из - за двух' - ' расширенных символов ascii в первом слове.

Есть идеи, что не так? Спасибо!

1 3

1 ответ:

Если вы хотите использовать многобайтовые символы UTF-8, вы должны использовать версию библиотеки ncurses, скомпилированную с поддержкой многобайтовых символов, и вам нужно правильно установить языковой стандарт в начале вашей программы.

Многобайтовая библиотека ncurses обычно называется libncursesw, поэтому для ее использования достаточно изменить -lncurses на -lncursesw в параметрах компоновщика. Вам не нужен другой файл заголовка. Однако, если вы действительно хотите использовать функции широких символов, вы должны #define символ _XOPEN_SOURCE_EXTENDED перед любой директивой #include. Самый простой способ сделать это с помощью gcc (или clang) - добавить -D_XOPEN_SOURCE_EXTENDED в параметры компилятора.

Если локаль вашей оболочки была установлена на UTF-8 (что обычно имеет место в современном дистрибутиве Linux), достаточно вставить

setlocale(LC_ALL, "");

Перед любым вызовом процедуры ncurses. Это устанавливает языковой стандарт исполняемого файла в соответствии с языковым стандартом, настроенным переменными среды. Вам нужно будет добавить

#include <locale.h>

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


Первоначальный вопрос указывал на то, что mvaddwstr используется. Как правило, это лучшее решение для многобайтовых символов, но, как указано выше, вы можете использовать узкие строковые интерфейсы, если хотите. Однако вы не можете вывести неполные последовательности UTF-8, поэтому односимвольные узкие интерфейсы, такие как addch, могут использоваться только с кодами символов меньше 128.

Это примечание применяется к попытке вызвать mvaddwstr с помощью char* вместо аргумента wchar_t*. Не делайте этого:

Как и все функции w ncurses, которые принимают строки, mvaddwstr принимает wchar_t* в качестве строкового аргумента. Ваш компилятор должен был предупредить вас об этом (если только он не предупредил вас, что не существует прототипа для mvaddwstr). Поэтому строки должны иметь префикс с атрибутом длины L: L"ñandñ".