printw (ncurses) 在 c 中没有显示正确的字符

printw (ncurses) not displaying correct char in c

我正在使用 ncurses 做一种模拟城市模拟器。

我在 .txt 中有 ascii 映射,我需要在终端上加载它。

加载良好,但显示的字符不正确(仅限某些字符)。

例如:

在 .txt 中 -> 在终端中

│ -> �~T~B

═ -> �~U~P

( -> (

我正在使用 http://www.theasciicode.com.ar/ 作为 ascii 映射

下面是在终端显示地图的代码

nt setUpMap(){

FILE *fp;
int c;

fp = fopen("./files/map.txt", "r+");

cbreak();

// Read and display data 

while ((c = fgetc(fp)) != EOF)
{
    switch(c){
        case 'p' :
            // todo : emoji
        break;
        default:
            printw("%c", c);
        break;
    }    
}

fclose(fp);

return 0;
}

.txt 内容示例:

┌───────────────────────┐
│   []   []   []   []   │
│ []  []   []   []   [] │
│   []   []   []   []   │
│                       │
│   ┌──┐       ┌──┐     │
└───┘  └───────┘  └─────┘

终端输出:

�~T~L�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@    �~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~P
�~T~B   []   []   []   []   �~T~B
�~T~B []  []   []   []   [] �~T~B
�~T~B   []   []   []   []   �~T~B
�~T~B                       �~T~B
�~T~B   �~T~L�~T~@�~T~@�~T~P       �~T~L�~T~@�~T~@�~T~P     �~T~B
�~T~T�~T~@�~T~@�~T~@�~T~X       �~T~T�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~@�~T~X      �~T~T�~T~@�~T~@�~T~@�~T~@�~T~@�~T~X

感谢任何想法

一般来说,curses 将显示 POSIX 字符集 printable 字符。对于其他任何事情,还有额外的步骤(和限制)。

对于 ncurses,您必须初始化语言环境以使其打印代码 160-255 作为字符。在 ncurses 手册的 initialization.

部分中提到了这一点

但是如果您的语言环境使用 UTF-8 编码(就像典型的开箱即用 "desktop" 系统那样),那么 ncurses 将期望应用程序提供 UTF-8 的字节,例如,使用 addchaddstrprintw可能在那种情况下工作,尽管没有人评论这种特殊情况的成功(或失败)。

如果值为 128-159,其中一些字节(指 addch)可能是 UTF-8 编码字符的一部分,并且取决于您是否在 ncurses 中初始化了语言环境,您会得到不同的结果。

无论哪种方式(128-159 或 160-255),当 ncurses 在显示 UTF-8 的终端中打印这些值时,您将获得如下所示的行为。

0-255 范围内的其他值是控制字符。

由于您的示例使用 fgetc,我们不需要考虑超过 255 的值。

假设您的示例是 UTF-8 格式,此程序(与 ncurseswwide-character library 链接)将按预期显示文本:

#include <curses.h>
#include <locale.h>

int
main(void)
{
    FILE *fp;
    int c;

    setlocale(LC_ALL, "");

    fp = fopen("./files/map.txt", "r");
    if (fp == 0)
        return 1;

    initscr();
    cbreak();
    noecho();

    // Read and display data 

    while ((c = fgetc(fp)) != EOF) {
        switch (c) {
        case 'p':
            // todo : emoji
            break;
        default:
            printw("%c", c);
            break;
        }
    }
    getch();
    endwin();

    fclose(fp);

    return 0;
}

要使用扩展的 ascii 字符,您需要使用 nursesw 而不是 ncurses

您将需要 apt-get ncursesw 才能使用它

你的 main 中的 include 仍然存在 #<ncurses.h>

当你编译的时候,你把 -lncursesw