NCurses getch总是返回ERR(-1)

时间:2018-05-20 18:24:36

标签: c++ linux ncurses ros stringstream

我刚刚开始使用ROS,而我正在尝试编写一个在主题中发布密钥的节点。

我使用ncurses在Linux Ubuntu 16.04.4上创建了一个节点。

这是我的代码:

#include <curses.h>

#include "ros/ros.h"
#include "std_msgs/String.h"

#include <sstream>

int main(int argc, char **argv)
{
    int ch;
    nodelay(stdscr, TRUE);

    ros::init(argc, argv, "keyboard_driver");

    ros::NodeHandle n;

    ros::Publisher key_pub = n.advertise<std_msgs::String>("keys", 1);

    ros::Rate loop_rate(100);

    while (ros::ok())
    {
        std_msgs::String msg;
        std::stringstream ss;

        if ((ch = getch()) != ERR)
        {
            ss << ch;
            std::cout << ch;
            msg.data = ss.str();

            ROS_INFO("%s", msg.data.c_str());

            key_pub.publish(msg);
        }

        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}

我使用ncurses来避免终端缓冲。

主题出现,但如果在另一个终端中我运行此命令,则无法获得任何内容:

rostopic echo /keys

调试它我发现getch()总是返回-1。

如何才能让它发挥作用?

更新

我尝试过这个小程序,并没有打印任何东西:

#include <iostream>
#include <curses.h>

int main(int argc, char **argv)
{
    int ch;
    cbreak();
    nodelay(stdscr, TRUE);

    for(;;)
    {
        if ((ch = getch()) != ERR)
        {
            std::cout << ch;
        }
    }

    return 0;
}

2 个答案:

答案 0 :(得分:3)

您已设置nodelay,因此如果终端没有准备好数据,则getch将立即返回ERR。这就是getch返回-1(ERR)的原因。你没有设置cbreak或raw来禁用终端缓冲,所以你仍然得到了 - 在 Enter 被击中之前,终端不会有任何数据。

所以在开始时(在调用cbreak()之前或之后)添加对nodelay()的调用,它应该按预期工作。

答案 1 :(得分:0)

要使用getch(),您必须执行以下操作:

#include <iostream>
#include <curses.h>
#include <signal.h>
#include <stdlib.h>

void quit(int sig)
{
    endwin();
    exit(0);
}

int main(int argc, char **argv)
{
    int ch;

    signal(SIGINT,quit);

    initscr();
    cbreak();
    nodelay(stdscr, TRUE);

    for(;;)
    {
        if ((ch = getch()) != ERR)
        {
            std::cout << ch;
        }
    }

    return 0;
}

我忘记在开头添加initscr();来电,在节目结束时添加endwin();

有关如何使用ncurses库here的更多信息。