wprintw:在ncurses中,当写入与窗口宽度完全相同的换行符终止行时,会打印两个换行符

M_M*_*M_M 5 c newline ncurses

我刚刚完成了 CLI 程序的代码,并使用 ncurses 将其转换为 TUI 程序。

它以类似于抽认卡的方式测试用户的一系列问题和答案。

除了我用弹出窗口的函数替换了许多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)
Run Code Online (Sandbox Code Playgroud)

wprintw()在使用打印到该窗口之前计算窗口的大小。

我遇到的问题是,当最后一行以外的一行的长度恰好等于窗口宽度(或窗口宽度的倍数)时,窗口中将省略一行或多行文本。

例如:

Answer:

Foobarbaz.
Run Code Online (Sandbox Code Playgroud)

将正确打印,但在:

Answer:

Foo.
Run Code Online (Sandbox Code Playgroud)

“福”。未打印。

我相信这是因为该wprintw()函数在打印字符后将光标移动到新行(window_width),但随后又遇到了刚刚打印的行末尾的换行符。

有谁知道一种方法(不需要自己编写整个函数来处理输出)来阻止这种情况发生?

有用的细节:

我正在替换:

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

和:

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

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();
}
Run Code Online (Sandbox Code Playgroud)

也有用:

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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

其他功能:

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)
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅 CLI 和 ncurses 版本的完整源代码,可以在http://github.com/megamasha找到

Arm*_*ali 3

当你说:

我相信这是因为 wprintw() 函数在打印 (window_width) 字符后将光标移动到新行,但随后又遇到了刚刚打印的行末尾的换行符。

关于你的问题

有谁知道一种方法(不需要自己编写整个函数来处理输出)来阻止这种情况发生?

- 没有这样的方法,因为你观察到的是 ncurses 中换行的工作原理。您可以做的是将弹出窗口加宽一个字符,从而避免由于达到窗口宽度而导致的换行,例如将行更改width+=8;width+=8+1;in popupinfo