【问题标题】:C++: how to input text in console and keep it at the bottomC ++:如何在控制台中输入文本并将其保留在底部
【发布时间】:2019-02-20 09:08:48
【问题描述】:

问题描述:

  • 我编写了一个经常打印出一些信息的程序。
  • 我想在程序运行过程中输入一些命令。
  • std::out 将清除我的输入。

例如:

>>> ./my_program
[sensorA] initial...ok
[sensorB] initial...ok
ge //!< I want to input 'get' here but the next output break it
[motorA] self-check...ok
t //!< break it into two spice

预期:

>>> ./my_program
[sensorA] initial...ok
[sensorB] initial...ok
[motorA] self-check...ok
get //!< always fixed here whenever I input

非常感谢!

【问题讨论】:

  • @SamVarshavchik 好的,很抱歉,我现在改正了。
  • 对于这样的事情,需要使用操作系统特定的功能。这不在 C++ 标准中。例如,在 Linux 上,对所有输入和输出使用 curses 库就足够了。

标签: c++


【解决方案1】:

欣赏

首先,我非常感谢Sam Varshavchik


我发现的主要结果

Sam 给了我使用Curses Library 的提示。我阅读了文档,现在完成了基本功能。

我的方法是创建子窗口(output_win 和 input_win)。用户输入显示在input_win,而程序信息打印在output_win
让我分享我的代码:

#include <iostream>
#include <string>
#include <curses.h>
#include <thread>
#include <atomic>
#include <chrono>
#include <unistd.h>

using namespace std;

WINDOW* win;
WINDOW* output_win;
WINDOW* input_win;
int row = 0, col = 0;
std::atomic<bool> flag(false);
string buf;

void ninit()
{
    win = initscr();
    getmaxyx(win, row, col);

    cbreak();
    noecho();

    nonl();
    intrflush(stdscr, FALSE);
    keypad(stdscr, TRUE);
    refresh();
}

void nprintf(string str)
{
    touchwin(win);
    str += '\n';
    wprintw(output_win, str.c_str());
    wrefresh(output_win);
}

void nprintf(const char* fmt, ...)
{
    touchwin(win);

    va_list ap;
    va_start(ap, fmt);
    vw_printw(output_win, fmt, ap);
    va_end(ap);

    wrefresh(output_win);
}

void nmonitor()
{
    while(1)
    {
        char x = getch();

        if(x != '\r')
        {
            touchwin(win);
            buf += x;
            waddch(input_win, x);
        }
        else
        {
            nprintf(buf);
            touchwin(input_win);
            flag = true;
            wclear(input_win);
        }
        wrefresh(input_win);
    }
}

string nget()
{
    while(!flag)
        usleep(100);
    string cmd = buf;
    flag = false;
    buf = "";
    return cmd;
}

////////////////////////////////

void print_thread()
{
    while(1)
    {
        static int i = 0;
        nprintf("no.%d\n", i++);
        usleep(100000);
    }
}

int main()
{
    ninit();
    fflush(stdin);

    output_win = subwin(win, row - 1, col, 0, 0);
    scrollok(output_win, true);
    input_win = subwin(win, 1, col, row - 1, 0);

    std::thread pthr(print_thread);
    std::thread nthr(nmonitor);

    string cmd;
    while(1)
    {
        cmd = nget();
        if(cmd == "quit")
            break;
        else
            nprintf("[info] You input: %s\n", cmd.c_str());
    }

    getch();

    endwin();
}

环境配置和构建

对于 Mac OSX:

brew install ncurses

对于 Ubuntu:

sudo apt-get install libcurses5-dev

构建:

g++ f04.cpp - f04 -lcurses  # I try for 4 times so name it f04

一些错误

其实它有一些bug,在这里我发现了:

  • 当你输入退格时,它不会删除一个字符而是显示一个特殊的字符;
  • 输入enter后,output_win有时会显示一些奇怪的字词。

我是初学者,可能需要帮助。 (也许我很快就会解决它们。)

愿它确实可以帮助别人。

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    1. 在打印之前,从标准输入读取用户的所有内容 到目前为止输入。
    2. 如果标准输入中有内容,请打印“\r”(这样下一个输出将覆盖用户输入的文本)。
    3. 打印您的输出。
    4. 打印用户到目前为止输入的文本(但没有'\n')。

    另请参阅: Rewinding std::cout to go back to the beginning of a line

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-26
      • 2012-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 2011-08-11
      相关资源
      最近更新 更多