在UTF-8中阅读ncurses标准

在UTF-8中阅读ncurses标准,c,utf-8,ncurses,C,Utf 8,Ncurses,在我用C语言开发的Linux程序中,我需要读取UTF-8编码的stdin。然而,每当我这样做: wint_t unicode_char=0; get_wch(&unicode_char); 我使用utf-16编码获得宽字符(当我使用gdb转储变量时可以看到它)。我不想将其从utf-16转换为utf-8,我想强制输入始终使用utf-8,无论哪个Linux发行版使用用户配置的任何外语运行我的程序。这是怎么做到的?可能吗 编辑: 下面是示例源代码,并证明内部get_wch使用UTF-16(与

在我用C语言开发的Linux程序中,我需要读取UTF-8编码的stdin。然而,每当我这样做:

wint_t unicode_char=0;
get_wch(&unicode_char);

我使用utf-16编码获得宽字符(当我使用gdb转储变量时可以看到它)。我不想将其从utf-16转换为utf-8,我想强制输入始终使用utf-8,无论哪个Linux发行版使用用户配置的任何外语运行我的程序。这是怎么做到的?可能吗

编辑: 下面是示例源代码,并证明内部get_wch使用UTF-16(与UTF-32相同)而不是UTF-8,尽管我使用setlocale()配置了UTF-8输入源

[niko@dev1ncurses]$gcc-g-ogetch-std=c99$(ncursesw5 config--cflags--libs)getch.c
[niko@dev1ncurses]$cat getch.c
#定义GNU源
#包括
#包括
#包括
#包括
#包括
int-ct;
温特尤尼卡;
int main(int argc,char*argv[])
{
setlocale(LC_ALL,“”;/*确保UTF8*/
initscr();
原始();
键盘(stdscr,真);
ct=get_wch(&unichar);/*读取字符*/
mvprintw(24,0,“按下的键=%4x”,unichar);
刷新();
getch();
endwin();
返回0;
}
使用GDB测试代码:


Short:you没有从中获得
UTF-8
。返回一个
wint
(和一个状态代码)

Long:您将从ncurses获得
UTF-8
,因为它在内部转换为/from
wchar\t

  • 您的程序必须一次读取一个字节的编码字符,因为
    getch
    只返回字节(可能与视频属性组合)
  • ncurses将
    wchar\u t
    值存储在每个窗口结构的单元格中
  • addch
    和朋友们尝试为多字节编码收集字节(它不是
    UTF-8
    特有的,但除此之外没有太多使用)
  • 如果将光标移到字符串中间,则尝试失败。
至于它的价值,请使用
getch
阅读UTF-8。看看它在实践中是如何工作的


X/Open curses本身并不能做到这一点(对于实际使用UTF-8的Unix curses的少数人来说,没有指定的方法)。

只是猜测:也许设置区域设置会有所帮助?如果您想要UTF-8,为什么要阅读宽字符?顺便说一句,Linux上的UTF-16并不是随机软件通常支持的东西。您可能会得到UCS4。“我想强制输入始终使用UTF-8”。您需要一个函数
强制将所有内容\u强制为\u utf8()
,但它还不存在。您需要以某种方式确定输入编码(这通常是不可能的),然后自己将其转换为UTF-8。@DanielJour我在程序开始时已经设置了locale(LC_ALL,“”),但它没有多大帮助。例如,如果我强制使用setlocale(LC_ALL,“en_US.UTF-8”),我将在所有非英语的外语输入中遇到问题。或者可以将locale设置为:setlocale(LC_ALL,“*.UTF-8”)?如果不是,这可能会向软件维护人员提出建议?@Nulik是的,UTF-8可以用多个字节编码。但是getch()将只读取1个字节。您当前的方法最有可能在任何地方都适用。get_wch()将转换使用的任何编码的输入,mvprintw()将输出转换回用户使用的编码(在这两种情况下很可能都是UTF-8)。将单个整数视为多字节编码的UTF-8字符是您不需要做的事情-您是否有这样做可以解决的特定问题?
[niko@dev1 ncurses]$ gcc -g -o getch -std=c99 $(ncursesw5-config --cflags --libs) getch.c 
[niko@dev1 ncurses]$ cat getch.c 
#define _GNU_SOURCE
#include <locale.h>
#include <ncursesw/ncurses.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int ct;
wint_t unichar;

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, ""); /* make sure UTF8 */
    initscr();
    raw();
    keypad(stdscr, TRUE);
    ct = get_wch(&unichar); /* read character */
    mvprintw(24, 0, "Key pressed is = %4x ", unichar);

    refresh();
    getch();
    endwin();
    return 0;
}