wprintw: в ncurses, при написании строки, оканчивающейся новой строкой, точно такой же ширины, что и окно, выводятся две строки - PullRequest
2 голосов
/ 24 сентября 2011

Я только что закончил работу с кодом программы CLI, преобразовав его в программу TUI с помощью ncurses.

Он тестирует пользователя на наборе вопросов и ответов в виде флеш-карты.

Все прошло относительно гладко, за исключением того, что я заменил многие вызовы printf() на функцию popupinfo(int colour,char * title, char * body) для вызова окна.
Эта функция использует следующие функции:

int textwidth (char * text);//returns the width of a given string (which may include newlines) in chars when displayed without wrapping (for purposes of determining optimum window width)
int textheight (char * text, int width);//returns the height of a given string (which may include newlines) in lines when displayed wrapped to the given width (for purposes of determining optimum window width)

для расчета размера окна перед использованием wprintw() для печати в этом окне.

Проблема, с которой я столкнулся, заключается в том, что когда длина строки, отличной от последней строки, точно равна ширине окна (или кратное ширине окна), одна или несколько строк текста будут опущены в окне.

Например:

Answer:

Foobarbaz.

будет печататься правильно, но в:

Answer:

Foo.

Фу.не печатается.

Я полагаю, это потому, что функция wprintw() перемещает курсор на новую строку после печати символов (window_width), но затем встречает символ новой строки, который был в конце строки, он простотакже напечатано.

Кто-нибудь знает способ (если не написать всю функцию для обработки вывода самостоятельно), чтобы остановить это?

Полезные сведения:

I 'm заменяет:

printf("\nSorry, the correct answer is:\n\n\t%s\n\n",currententry->answer);

на:

sprintf(passingstring,"The correct answer is:\n\n%s",currententry->answer);
popupinfo(3,"Sorry!",passingstring);

popupinfo определяется как:

void popupinfo(int colour,char * title,char * message)//pops up a window with the given colour, title and text
{
    WINDOW * wbpopup = NULL, * wpopup = NULL;
    PANEL * ppopup = NULL;
    int width, height;

    width=textwidth(message);
    getmaxyx(stdscr,nlines,ncols);
    if (width>ncols-16)width=ncols-16;
    height=textheight(message,width)+4;
    width+=8;
    if (!(wbpopup = newwin(height,width,(nlines-height)/2,(ncols-width)/2))) outofmemory();
    ppopup = new_panel(wbpopup);
    wattrset(wbpopup,COLOR_PAIR(colour));
    werase(wbpopup);
    wbkgd(wbpopup,COLOR_PAIR(colour));
    box(wbpopup,0,0);
    windowtitle(wbpopup,title);
    wpopup = innerwindow(wbpopup);

    wprintw(wpopup,message);
    update_panels();
    doupdate();
    wgetch(wpopup);

    delwin(wpopup);
    del_panel(ppopup);
    delwin(wbpopup);
    update_panels();
    doupdate();
}

Также полезно:

int textwidth (char * text)//returns the width of a given string (which may include newlines) in chars when displayed without wrapping (for purposes of determining optimum window width)
{
    int i=0,j=0,k=0;
    while (text[i]!='\0')
    {
        if (text[i]=='\n')
        {
            k=j>k?j:k;
            j=0;
        }
        else j++;
        i++;
    }
    k=j>k?j:k;
    return k;
}

и

int textheight (char * text, int width)//returns the height of a given string (which may include newlines) in lines when displayed wrapped to the given width (for purposes of determining optimum window width)
{
    int i=0,j=0,k=1;
    while (text[i]!='\0')
    {
        if (text[i]=='\n')
        {
            k++;
            j=0;
        }
        else j++;
        if (j>width)
        {
            k++;
            j=1;
        }
        i++;
    }
    return k;
}

Другие функции:

WINDOW * innerwindow(WINDOW * outerwindow);//creates an area within another window for purposes of displaying text with a margin
void windowtitle(WINDOW * window, char * title);//writes the given string to the given window (top centre)

Для получения дополнительной информации см. Полный исходный код версий CLI и ncurses, который можно найти по адресу http://github.com/megamasha

Anyочень помог бы.

PS Я бы пометил этот wprintw, но у меня недостаточно репутации для создания новых тегов.

1 Ответ

1 голос
/ 03 марта 2014

Вы абсолютно правы, когда говорите:

Я полагаю, это потому, что функция wprintw () перемещает курсор в новая строка после печати (window_width) символов, но затем встречает символ новой строки, который был в конце строки, он просто печатался как хорошо.

По вашему вопросу

Кто-нибудь знает способ (если не считать написания всей функции для обрабатывать вывод сам) чтобы это не случилось?

- такого способа нет, потому что вы наблюдаете, как работает перенос строк в ncurses. То, что вы могли бы сделать, это сделать всплывающее окно на один символ шире, что позволит избежать переноса, вызванного достижением ширины окна, например, путем изменения строки width+=8; на width+=8+1; в popupinfo.

...