无法从 NCURSES 中的标准输入扩展 ASCII 字符读取

Cannot read from stdin extended ASCII character in NCURSES

我在尝试读取 NCURSES 中的扩展 ASCII 字符时遇到问题。

我有这个程序:

#include <ncurses.h>
int main () {
    initscr();
    int d = getch();
    mvprintw(0, 0, "letter: %c.", d);
    refresh();
    getch();
    endwin();
    return 0;
}

我用:gcc -lncursesw a.c

如果我在 7 位 ascii 中输入一个字符,比如 'e' 字符,我得到:

letter: e.

然后我必须再输入一个程序才能结束。

如果我在扩展的 ascii 中键入一个字符,例如 'á' 字符,我得到:

letter:  .

程序结束。

好像第二个字节被当作另一个字符读取了。

如何获得正确的字符 'á' ???

谢谢!

您要输入的字符需要程序设置 locale。如 manual:

中所述
Initialization

   The  library uses the locale which the calling program has
   initialized.  That is normally done with setlocale:

         setlocale(LC_ALL, "");

   If the locale is not initialized, the library assumes that
   characters  are  printable  as in ISO-8859-1, to work with
   certain legacy programs.  You should initialize the locale
   and  not  rely on specific details of the library when the
   locale has not been setup.

除此之外,您的语言环境很可能使用 UTF-8。要使用 UTF-8,您应该针对 ncursesw 库进行编译和 link。

此外,getch 函数仅为单字节编码的 returns 值,例如 ISO-8859-1,有些人将其与 Windows cp1252 混淆,因此 "Extended ASCII"(这说明两个谬误没有抵消)。 UTF-8 是一种多字节编码。如果用getch读取that,就会得到字符的第一个字节

相反,要阅读 UTF-8,您应该使用 get_wch(除非您想自己解码 UTF-8)。这是一个修改后的程序:

#include <ncurses.h>
#include <locale.h>
#include <wchar.h>
int
main(void)
{   
    wint_t value;
    setlocale(LC_ALL, "");
    initscr();
    get_wch(&value);
    mvprintw(0, 0, "letter: %#x.", value);
    refresh();
    getch();
    endwin();
    return 0;
}

我将结果打印为数字,因为 printw does not know about Unicode values. printw uses the same C runtime support as printf, so you may be able to print the value directly. For instance, I see that POSIX printf 有一个用于处理 wint_t:

的格式选项

c
The int argument shall be converted to an unsigned char, and the resulting byte shall be written.
If an l (ell) qualifier is present, the wint_t argument shall be converted as if by an ls conversion specification with no precision and an argument that points to a two-element array of type wchar_t, the first element of which contains the wint_t argument to the ls conversion specification and the second element contains a null wide character.

由于 ncurses 适用于许多平台,并非所有这些平台实际上都支持 该功能。但您可以假设它适用于 GNU C 库:大多数发行版通常都提供可行的语言环境配置。

这样做,这个例子比较有意思:

#include <ncurses.h>
#include <locale.h>
#include <wchar.h>
int
main(void)
{   
    wint_t value;
    setlocale(LC_ALL, "");
    initscr();
    get_wch(&value);
    mvprintw(0, 0, "letter: %#x (%lc).", value, value);
    refresh();
    getch();
    endwin();
    return 0;
}