【问题标题】:getline() and ncurses output not idealgetline() 和 ncurses 输出不理想
【发布时间】:2015-03-07 17:40:59
【问题描述】:

如果我有

#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 >> name 像这样:

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

那么我的输出是这样的:

(NA) is not in a game.                   imaqtpie

由于某种原因,发送过去“名称”的所有内容都会发送到行首。我猜这可能是 getline() 在“名称”的末尾推了一些东西,这 ncurses mvprintw 输出并没有享受太多。除此之外,我想不出问题是什么,因为 getline() 应该与 >> 运算符几乎相同。我尝试用 getline() 替换所有内容无济于事。我需要“名称”来包含空格的可能性,那么我的其他选择是什么? (在没有 ncurses 的情况下尝试这个,而是使用 cout

【问题讨论】:

  • 我猜这可能是 getline() 在 "name" 末尾添加了一个转义字符,如 \n - 不,它没有,并且阅读了一些 @ 987654321@ 在您不知道其行为的函数上是个好主意。

标签: c++ getline ncurses


【解决方案1】:

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

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

如果您必须混合 stdio 和 ncurses,则必须执行 fflush 以确保在切换回 ncurses 之前完成编写(以及在返回之前 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();
}

【讨论】:

  • 感谢您的回复。我在 initscr() 中进行了编辑以显示它最初的样子。我现在(在我自己的代码中)在 nameserverinput.close() 之后放置了 initsrc() 初始化,并在它之前放置了 fflush(stdout) 和 fflush(stderr) (为了安全起见),但我仍然有问题(我还注释掉任何使用 cout 是安全的)
  • 只是一个有点没用的fyi,“postgame”变量不应该在我的代码中,忘了把它拿出来。复制您刚刚重新发布的代码,我的输出肯定会根据是否使用 getline() 发生变化。如果这有什么不同,我会在 Linux(树莓派)上运行它。
  • 我不希望这会有所作为(我在 Debian6 上使用当前稳定的 ncurses 进行了测试,以防万一,但没有匹配的配置)。
  • 很公平,您是否碰巧使用 fflush 让它工作?如果不是,我可能会尝试像您暗示的那样避免使用 stdio,而只是在源代码中写入名称/服务器/显示值。
  • 实际上,一旦我能够运行该示例,我就没有看到任何内容进入标准输出——只有 ncurses 输出。也许问题不在于 ncurses,而在于 C++ 运行时(您使用的是哪个版本的 g++?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多