Терминал Linux ничего не отображает с помощью ncurses

Я пытаюсь создать библиотеку, чтобы упростить использование ncurses для отображения цветов. Я делаю это объектно-ориентированным, поэтому в будущем будет легко обрабатывать изменения. Но проблема в том, что я не могу заставить работать этот код.

#include <ncurses.h>
#include <string.h> 
#include <string>
#include <unistd.h>
#include <iostream>

using namespace std;

class ColorWindow {
    private:
        bool canColor;
        WINDOW* container;
        int height, width, startx, starty;

    public:
        ColorWindow() {
            if(has_colors()) {
                canColor=true;
            }

            this->height = 20;
            this->width = 84;
            this->starty = (LINES - height) / 2;    /* Calculating for a center placement */
            this->startx = (COLS - width) / 2;
        }

        bool writeStringWithColor(int x, int y, const char* message) {
            if(!canColor) {
                writeString(3, 5, "Sorry, your term can't show colors.");
                return false;
            }

            init_pair(1, COLOR_RED, COLOR_BLACK);

            writeString(0, 10, "aaaaaaaaa");

            wattron(getContainer(), COLOR_PAIR(1));
            writeString(x, y, message);
            wattroff(getContainer(), COLOR_PAIR(1));
        }

        void writeString(int x, int y, const char* message) {
            mvwprintw(getContainer(), x, y, message);
        }

        WINDOW* createNewContainer() {
            this->container = newwin(height, width, starty, startx);
            wrefresh(this->container);      /* Show that box        */

            return getContainer();
        }

        WINDOW* getContainer() {
            return this->container;
        }

        void refreshContainer() {
            refresh();
            wrefresh(this->container);      /* Show that box        */
        }       
};

int main() {
    ColorWindow cw = ColorWindow();


    initscr();          /* Start curses mode        */
    cbreak();           /* Line buffering disabled, Pass on
                        * everything to me      */
    keypad(stdscr, TRUE);
    start_color();

    cw.createNewContainer();

    bool success = cw.writeStringWithColor(0, 10, "Hello everyone in color!!");
    if(!success)
        cw.writeString(0, 10, "Write with color failed :(");
    cw.refreshContainer();
    sleep(2);
    endwin();

    return 0;
}

Заранее спасибо.


person Shirkam    schedule 23.07.2016    source источник
comment
canColor выглядит потенциально неинициализированным для меня. container тоже выглядит неинициализированным.   -  person melpomene    schedule 23.07.2016
comment
Он будет отображать Извините, ваш термин [...], если это так, но он отображает что угодно, даже строку aaaaaa, которую я там написал.   -  person Shirkam    schedule 23.07.2016


Ответы (1)


В вашем коде есть пара ошибок:

  • Вы не инициализируете canColor и container, поэтому копирование полей в cw в main имеет неопределенное поведение. Исправлено:

    ColorWindow() : canColor(false), container(nullptr) {
    
  • В writeStringWithColor отсутствует оператор return в конце, что также приводит к неопределенному поведению в main. Исправлено:

    return true;
    

    в конце writeStringWithColor.

  • Ваши аргументы x и y меняются местами при вызове mvwprintw в writeString. Исправлено:

    mvwprintw(getContainer(), y, x, message);
    
  • LINES и COLS действительны только после инициализации ncurses, поэтому ваши значения starty и startx - мусор. Исправлено перемещением инициализации cw после кода инициализации ncurses в main:

    initscr();          /* Start curses mode        */
    cbreak();           /* Line buffering disabled, Pass on
                        * everything to me      */
    keypad(stdscr, TRUE);
    start_color();
    
    ColorWindow cw = ColorWindow();
    

Полная программа:

#include <ncurses.h>
#include <string.h> 
#include <string>
#include <unistd.h>
#include <iostream>

using namespace std;

class ColorWindow {
    private:
        bool canColor;
        WINDOW* container;
        int height, width, startx, starty;

    public:
        ColorWindow() : canColor(false), container(nullptr) {
            if(has_colors()) {
                canColor=true;
            }

            this->height = 20;
            this->width = 84;
            this->starty = (LINES - height) / 2;    /* Calculating for a center placement */
            this->startx = (COLS - width) / 2;
        }

        bool writeStringWithColor(int x, int y, const char* message) {
            if(!canColor) {
                writeString(3, 5, "Sorry, your term can't show colors.");
                return false;
            }

            init_pair(1, COLOR_RED, COLOR_BLACK);

            writeString(0, 10, "aaaaaaaaa");

            wattron(getContainer(), COLOR_PAIR(1));
            writeString(x, y, message);
            wattroff(getContainer(), COLOR_PAIR(1));
            return true;
        }

        void writeString(int x, int y, const char* message) {
            mvwprintw(getContainer(), y, x, message);
        }

        WINDOW* createNewContainer() {
            this->container = newwin(height, width, starty, startx);
            wrefresh(this->container);      /* Show that box        */

            return getContainer();
        }

        WINDOW* getContainer() {
            return this->container;
        }

        void refreshContainer() {
            refresh();
            wrefresh(this->container);      /* Show that box        */
        }       
};

int main() {
    initscr();          /* Start curses mode        */
    cbreak();           /* Line buffering disabled, Pass on
                        * everything to me      */
    keypad(stdscr, TRUE);
    start_color();

    ColorWindow cw = ColorWindow();

    cw.createNewContainer();

    bool success = cw.writeStringWithColor(0, 10, "Hello everyone in color!!");
    if(!success)
        cw.writeString(0, 10, "Write with color failed :(");
    cw.refreshContainer();
    sleep(2);
    endwin();

    return 0;
}
person melpomene    schedule 23.07.2016
comment
все еще нет (конструктор неисправен). - person Thomas Dickey; 23.07.2016
comment
@ThomasDickey Ну, по крайней мере, эта версия здесь дает видимый вывод. Чего не хватает? - person melpomene; 23.07.2016
comment
@melpomene Ну, это не работает для меня. Он показывает ту же белую консоль, что и моя тестовая программа. Нет видимого выхода для меня. Это не имеет смысла, потому что я попробовал другой простой пример, и он показывает красочный вывод. - person Shirkam; 24.07.2016