Search code examples
c++linuxncursesrosstringstream

NCurses getch always returns ERR (-1)


I've just started to work with ROS and I'm trying to write a node that publish keys in a topic.

I have created a node on a Linux Ubuntu 16.04.4 using ncurses.

This is my code:

#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;
}

I'm using ncurses to avoid terminal buffer.

The topic appears, but I don't get anything if, in another terminal, I run this command:

rostopic echo /keys

Debugging it I have found that getch() always return -1.

How can I do to make it work?

UPDATE

I have tried this small program, and it doesn't print anything:

#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;
}

Solution

  • To use getch() you have to do the following:

    #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;
    }
    

    I forget to add initscr(); call at the beginning and endwin(); at the end of the program.

    More info about how to use ncurses library here.