printw (ncurses) не отображает правильный символ в c

Я использую ncurses для создания своего рода симулятора города.

У меня есть карта ascii в формате .txt, и мне нужно загрузить ее на терминал.

Загрузка хорошая, но не отображаются правильные персонажи (только для некоторых персонажей).

Например:

в .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

спасибо за любые идеи


person Fire Frost    schedule 28.09.2017    source источник
comment
Я не думаю, что код, который вы разместили, показывает нам ошибку ... я предлагаю вам отредактировать его и опубликовать больше кода, а также часть файла .txt.   -  person Gam    schedule 28.09.2017
comment
@Gam Я отредактировал сообщение, теперь моя проблема более ясна?   -  person Fire Frost    schedule 29.09.2017
comment
Может быть, это поможет?   -  person Quentin Laillé    schedule 29.09.2017
comment
@QuentinLaillé, так что я должен сделать переключатель на входе, а затем вывести правильную константу?   -  person Fire Frost    schedule 29.09.2017
comment
Если вы измените printw() на printw("%d\n", c);, это те символы, которые вам нужны?   -  person Gam    schedule 29.09.2017


Ответы (2)


Вообще говоря, curses будет отображать печатаемые символы набора символов POSIX, как вы и предполагали. Для всего остального есть дополнительные шаги (и ограничения).

Для ncurses вам потребуется инициализировать языковой стандарт, чтобы он печатал коды 160–255 в виде символов. Это упоминается в разделе руководства по ncurses, посвященном инициализации. .

Но если ваша локаль использует кодировку UTF-8 (как это делает типичная готовая «настольная» система), то ncurses будет ожидать, что приложение предоставит байты для UTF-8, например, используя addch или addstr. printw может работать в этом случае, хотя никто не прокомментировал успех (или неудачу) в этом особом случае.

Если значение равно 128-159, некоторые из этих байтов (со ссылкой на addch) могут быть частью символа в кодировке UTF-8, и в зависимости от того, инициализировали ли вы локаль в ncurses, вы получите разные результаты.

В любом случае (128-159 или 160-255) вы получите поведение, как показано, когда ncurses печатает эти значения в терминале, который отображает UTF-8.

Другие значения в диапазоне 0–255 являются управляющими символами.

Поскольку в вашем примере используется fgetc, нам не нужно рассматривать значения выше 255.

Предполагая, что ваш пример находится в UTF-8, эта программа (связанная с ncursesw, широкосимвольная библиотека) отобразит текст так, как предполагалось:

#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;
}
person Thomas Dickey    schedule 29.09.2017
comment
Я пытался использовать setlocale, как они говорят при инициализации, но теперь он печатает разные символы, │ -> M-3 - person Fire Frost; 29.09.2017

Чтобы использовать расширенные символы ascii, вам нужно использовать Nursesw, а не ncurses.

вам нужно будет получить ncursew, чтобы использовать его

включение в ваш основной по-прежнему остается #<ncurses.h>

при компиляции ставите -lncursew

person Fire Frost    schedule 29.09.2017