简体   繁体   English

无法从 NCURSES 中的 stdin 扩展 ASCII 字符读取

[英]Cannot read from stdin extended ASCII character in NCURSES

I have a problem trying to read extended ASCII chars in NCURSES.我在尝试读取 NCURSES 中的扩展 ASCII 字符时遇到问题。

I have this program:我有这个程序:

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

I build it with: gcc -lncursesw ac我使用以下命令构建它:gcc -lncursesw ac

If I type a character in the 7bit ascii, like the 'e' char, I get:如果我在 7 位 ascii 中输入一个字符,比如“e”字符,我会得到:

letter: e.

And then I have to type another for the program to end.然后我必须键入另一个程序才能结束。

If I type a character in the extended ascii, like the 'á' char, I get:如果我在扩展的 ascii 中输入一个字符,比如 'á' 字符,我会得到:

letter:  .

and the program ends.程序结束。

Its like the second byte is read as another character.它就像第二个字节被读取为另一个字符。

How can I get the correct char 'á' ???我怎样才能得到正确的字符 'á' ???

Thanks!谢谢!

The characters that you want to type require the program to setup the locale .您要键入的字符需要程序设置语言环境 As described in the 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.

Past that, it is likely that your locale uses UTF-8.除此之外,您的语言环境很可能使用 UTF-8。 To work with UTF-8, you should compile and link against the ncursesw library.要使用 UTF-8,您应该针对ncursesw库进行编译和链接。

Further, the getch function only returns values for single-byte encodings, such as ISO-8859-1, which some people confuse with Windows cp1252 , and thence to "Extended ASCII" (which says something about two fallacies not cancelling out).此外, getch函数仅返回单字节编码的值,例如 ISO-8859-1,有些人将其与Windows cp1252混淆,然后返回“扩展 ASCII”(这说明了两个无法抵消的谬误)。 UTF-8 is a multibyte encoding. UTF-8 是一种多字节编码。 If you use getch to read that , you will get the first byte of the character.如果您使用getch读取该内容,您将获得该字符的第一个字节。

Instead, to read UTF-8 , you should use get_wch (unless you want to decode the UTF-8 yourself).相反,要读取UTF-8 ,您应该使用get_wch (除非您想自己解码 UTF-8)。 Here is a revised program which does that:这是一个修改后的程序,它可以做到:

#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;
}

I printed the result as a number, because printw does not know about Unicode values.我将结果打印为数字,因为printw不知道 Unicode 值。 printw uses the same C runtime support as printf , so you may be able to print the value directly. printw使用与printf相同的 C 运行时支持,因此您可以直接打印值。 For instance, I see that POSIX printf has a formatting option for handling wint_t :例如,我看到POSIX printf有一个用于处理wint_t的格式化选项:

c
The int argument shall be converted to an unsigned char , and the resulting byte shall be written. int参数应转换为unsigned char ,并写入结果字节。
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.如果存在l ( ell ) 限定符,则wint_t参数将被转换为好像由没有精度的ls转换规范和指向wchar_t类型的二元素数组的参数一样,其中的第一个元素包含wint_t参数到ls转换规范,第二个元素包含空宽字符。

Since ncurses works on many platforms, not all of those actually support the feature.由于 ncurses 适用于许多平台,并非所有平台都支持该功能。 But you can probably assume it works with the GNU C library: most distributions routinely provide workable locale configurations.但是您可能会假设它适用于 GNU C 库:大多数发行版通常都提供可行的语言环境配置。

Doing that, the example is more interesting:这样做,这个例子更有趣:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM