添加宽字符支持会破坏 ncurses 菜单

问题描述 投票:0回答:1

我目前正在尝试使用基本的 TUI 创建一个 ada 程序(这将在稍后相关)。 为此,我使用 ncurses,更具体地说,我与 C 交互,因为 ada 绑定 ncursesada 对我不起作用 [1]。

我想做的是一个基本的 ncurses 菜单。这是一个简单的菜单,包含三个选项,其中两个选项允许用户输入一个句子,然后我在主程序中使用该句子。由于我的输入句子是法语,我搜索了如何添加对宽字符的支持,并偶然发现了this post,这使我在配置文件中添加了一些编译器/链接器标志。就我而言,他们是:

编译器:-I/usr/include/ncursesw -D_DEFAULT_SOURCE -D_XOPEN_SOURCE_EXTENDED=600
链接器:-Wl,-Bsymbolic-functions -lncursesw -ltinfo

另外,我在

setlocale (LC_ALL, "")
之前添加了
initsrc
,并将相关宏
NCURSES_WIDECHAR
重新定义为 1,我知道我应该这样做。

有了这一切,我现在可以毫无问题地获得宽字符,但是,我的主菜单现在被破坏了。事实上,它不是显示完整选项,而是看起来有点被删减

在寻找解决方案时,我告诉自己也许问题出在 setlocale 函数上;这似乎不是问题。我还查看了这篇文章,其中描述了与 unicode 相关的 ncurses 的八个问题。我应该擅长八点[2]。在最后的努力中,我尝试删除编译器和链接器标志,并在适用的情况下从 wint_t(*) 回滚到 char(*)。令我惊讶的是,这解决了问题。 所以现在我陷入了僵局。我想使用 ncursesw 来访问宽字符,但如果我这样做,我的菜单似乎会损坏。我能做什么来解决这个问题? 我考虑过使用 ncurses 的替代品,但是:

快速搜索后,我在 C 中没有找到任何其他内容
  • 我不能真正使用 C++,因为根据我的理解,Ada 接口有点棘手,
  • C++ 没有定义的 ABI
  • ,这意味着,我认为,为每个平台指定编译器,或者减少我的目标范围。
  • 非常感谢,

[1] 使用alire命令安装,但是编译时,它抱怨一些libraires不存在。

[2] 也许不是第四点,它说“非常非常小心,不要使用实际上没有宽字符函数的库版本。”,但我没有找到如何使用带有 ncursesw 的菜单(我尝试导入

但它似乎没有做任何事情)。

编辑:这里应该是一个最小的可重现示例:

这样,我获得了

这个菜单

(有趣的是,这是一个与上面的菜单不同的损坏菜单) 编译为

gcc ncurses_external.c -I/usr/include/ncursesw -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -o main -lmenu -Wl,-Bsymbolic-functions -lncursesw -ltinfo

ncurses_external.h

#include <ncurses.h> #include <menu.h> #define INVISIBLE 0 #define VISIBLE 1 #define ENTER_CODE 10 #define SENTENCE 0 #define FILE_STR 1 char* Choices[] = { "Traduire (FR->NO)", "Traduire (NO->FR)", "Quitter" }; int InitScr_Wrp (); void Refresh_Wrp (); void Colored_Line (char Line[], short Color, int y); int Menu (int y); wint_t* Get (int type, int y); // the wint_t errors (underlined in an IDE) are IDE's specific error. Program // compile. int main (int argc, char *argv[]); void EndScr_Wrp (); // private in regards to Ada ITEM** Allocate_List (int N, char* choices[]); void Free (int N, ITEM** List, MENU* menu);

ncurses_external.c

#include "ncurses_external.h" #include <ncursesw/ncurses.h> #include <stdlib.h> #include <string.h> #include <locale.h> #define NCURSES_WIDECHAR 1 int InitScr_Wrp () { setlocale (LC_ALL, ""); initscr (); if (has_colors () == FALSE) { endwin (); return -1; } curs_set (INVISIBLE); cbreak (); noecho (); start_color (); keypad (stdscr, TRUE); return 0; } void Refresh_Wrp () { refresh (); } void Colored_Line (char Line[], short Color, int y) { init_pair (y, Color, COLOR_BLACK); attron (COLOR_PAIR (y)); mvwprintw (stdscr, y - 1, 0, "%s", Line); attroff (COLOR_PAIR (y)); } ITEM** Allocate_List (int N, char* choices[]) { ITEM** List; List = (ITEM**)calloc (N + 1, sizeof (ITEM*)); for (int i = 0; i < N; ++i) { List[i] = new_item (choices[i], ""); } return List; } void Free (int N, ITEM** List, MENU* menu) { unpost_menu (menu); free_menu (menu); for (int i = 0; i < N; i++) { free_item (List[i]); } } int Menu (int y) { ITEM** Item_List; WINDOW* menu_win; MENU* Option_Menu; menu_win = newwin (16, 50, y, 0); keypad (menu_win, TRUE); int N = sizeof (Choices) / sizeof (Choices[0]); Item_List = Allocate_List (N, Choices); Option_Menu = new_menu (Item_List); set_menu_win (Option_Menu, menu_win); set_menu_sub (Option_Menu, menu_win); post_menu (Option_Menu); wrefresh (menu_win); int character; int Choosen_Option = 0; menu_driver (Option_Menu, REQ_FIRST_ITEM); do { character = wgetch (menu_win); switch (character) { case KEY_UP: Choosen_Option = Choosen_Option > 0 ? Choosen_Option - 1 : 0; menu_driver (Option_Menu, REQ_UP_ITEM); break; case KEY_DOWN: Choosen_Option = Choosen_Option < N ? Choosen_Option + 1 : N; menu_driver (Option_Menu, REQ_DOWN_ITEM); break; } } while (character != ENTER_CODE); Free (N, Item_List, Option_Menu); wclear (menu_win); wrefresh (menu_win); delwin (menu_win); return Choosen_Option; } wint_t* Get (int type, int y) { if (type == SENTENCE) { mvwprintw (stdscr, y, 0, "Entrer une phrase à traduire :"); } else { mvwprintw (stdscr, y, 0, "Entrer un fichier à décoder :"); } mvwprintw (stdscr, y + 1, 0, "> "); wrefresh (stdscr); curs_set (VISIBLE); echo (); wint_t* response = NULL; size_t N = 0; size_t curr_end_size = 255; size_t Block = 16; response = (wint_t*)realloc (NULL, sizeof (*response) * curr_end_size); if (!response) return response; wint_t character; do { get_wch (&character); response[N] = character; N++; if (N == curr_end_size) { curr_end_size += Block; response = (wint_t*)realloc (response, sizeof (*response) * curr_end_size); if (!response) return response; } } while (character != ENTER_CODE); return response; } void EndScr_Wrp () { endwin (); } int main (int argc, char *argv[]) { int y1 = 10; int option; InitScr_Wrp (); option = Menu (y1); switch (option) { case (SENTENCE): Get (SENTENCE, y1); break; case (FILE_STR): Get (FILE_STR, y1); break; } EndScr_Wrp (); }

	
c ada ncurses widechar
1个回答
0
投票
-lmenuw

而不是

-lmenu
    

© www.soinside.com 2019 - 2024. All rights reserved.