getline()和ncurses输出不理想

getline() and ncurses output not ideal

本文关键字:输出 理想 ncurses getline      更新时间:2023-10-16

如果我有

#include <iostream>
#include <ncursesw/curses.h>
#include <fstream>
#include <string>
using namespace std;
int main(){
    initscr();
    curs_set(0);
    int row, col;
    getmaxyx(stdscr, row, col); //forgot these originally
    string name, server, displayanswer;
        ifstream nameserverinput("nameserver.txt");
        if(!nameserverinput.is_open()){
            erase();
            string error = "nameserver.txt could not be found. Exiting...";
            mvprintw(row/2 - 1, (col-error.size())/2, error.c_str());
            refresh();
            sleep(5);
            return 0;
        }
        nameserverinput >> name >> server >> displayanswer;
        nameserverinput.close();
    erase();
    string error = (name + " (" + server + ") " + "is not in a game.");
    mvprintw(row/2 - 1, (col-error.size())/2, error.c_str());
    refresh();
}

我的输出非常好,所有的东西都在一条线上。nameserver.txt的示例为:

imaqtpie
na
y

如果我用getline(nameserverinput,name)替换nameserverinput>>名称,如下所示:

 getline(nameserverinput, name)
 nameserverinput >> server >> displayanswer;

那么我的输出是:

(NA) is not in a game.                   imaqtpie

由于某种原因,所有发送到"name"之后的内容都会发送到行的开头。我猜这可能是getline()在"name"的末尾推挤了一些ncurses mvprintw输出不太喜欢的东西。除此之外,我想不出会有什么问题,因为getline()的工作方式应该与>>运算符几乎相同。我尝试用getline()替换所有内容,但没有成功。我需要"名称"来包含空间的可能性,那么我的其他选择是什么?(在不使用ncurses的情况下尝试,而使用cout<<x<<endl,这一切都很理想,所以这一定与混合getline()和ncurses有关)。

示例中缺少某些内容(从未调用initscr)。

但假设您只是在剪切/粘贴中忽略了这一点:getline将回显到标准输出。一般来说,您不能混合stdio和ncurses调用(或任何curses实现),因为ncurses在写入屏幕之前以自己的方式缓冲,并且缓冲区不一定是stdio已知的。

如果必须混合stdio和ncurses,则必须执行fflush的操作以确保在切换回ncurses之前已完成写入(以及在返回stdio之前执行refresh的操作)。

使用建议的修订(加上确保程序正常退出),我看到了与此示例中使用/不使用getline相同的行为:

#include <iostream>
#include <ncursesw/curses.h>
#include <fstream>
#include <string>
using namespace std;
int
main()
{
    initscr();
    curs_set(0);
    int row, col;
    getmaxyx(stdscr, row, col); //forgot these originally
    string name, server, displayanswer, postgameanswer;
    ifstream nameserverinput("nameserver.txt");
    if (!nameserverinput.is_open()) {
        erase();
        string error = "nameserver.txt could not be found. Exiting...";
        mvprintw(row / 2 - 1, (col - error.size()) / 2, error.c_str());
        refresh();
        sleep(5);
        wgetch(stdscr);
        endwin();
        return 0;
    }
#if 1
    getline(nameserverinput, name);
    nameserverinput >> server >> displayanswer >> postgameanswer;
#else
    nameserverinput >> name >> server >> displayanswer;
#endif
    nameserverinput.close();
    erase();
    string error = (name + " (" + server + ") " + "is not in a game.");
    mvprintw(row / 2 - 1, (col - error.size()) / 2, error.c_str());
    refresh();
    wgetch(stdscr);
    endwin();
}