4

I want to know how can i read the standard input just for 5 seconds like you just have 5 seconds to write.

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string mystr;
  cout << "What's your name? ";
  getline (cin, mystr);
  cout << "Hello " << mystr << ".\n";
  cout << "What is your favorite team? ";
  getline (cin, mystr);
  cout << "I like " << mystr << " too!\n";
  return 0;
}

Like that the user have all the time he want to write. Did getline or read have any option to force the getline to stop after 5sec ?

Thank you

drescherjm
  • 10,365
  • 5
  • 44
  • 64
  • 3
    there is no standard way. It's system dependent. – bolov May 07 '20 at 23:03
  • 1
    And can i make it with an other function ? – xXx_Ninj4_Kill3r_xXx May 07 '20 at 23:06
  • 3
    It's platform dependant. What platform, OS, Window Manager, etc are you using? – Jerry Jeremiah May 07 '20 at 23:19
  • If you are using Microsoft Windows, you can use the Console I/O functions, such as [`_kbhit`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/kbhit?view=vs-2019) and [`_getche`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getche-getwche?view=vs-2019). I don't know what the corresponding functions for Linux are. – Andreas Wenzel May 07 '20 at 23:23
  • I'm on Fedora 28 on linux and i can use any libraries i need – xXx_Ninj4_Kill3r_xXx May 07 '20 at 23:24
  • 4
    main thread spawn/fork/create reader thread. Wait 5 seconds, join reader thread. Problems with buffered input and a bunch of other things to watch, but it reads for 5 seconds :) – Michael Dorgan May 07 '20 at 23:26
  • Although I am not familiar with linux myself, I believe that it is common to use the [ncurses](https://en.wikipedia.org/wiki/Ncurses) library for console I/O. – Andreas Wenzel May 07 '20 at 23:27
  • 1
    For POSIX? Use [`select`](http://man7.org/linux/man-pages/man2/select.2.html). Keep in mind on Fedora you can use any *Linux* libraries you need. – tadman May 07 '20 at 23:46
  • https://stackoverflow.com/q/9053175/1216776 – stark May 08 '20 at 18:53

2 Answers2

1

A possible solution is to use poll() and write your own getline() function (tested on xubuntu 18.04 with g++ 7.5.0):

Here the implementation of my getline_timeout(int, std::string):

std::string getline_timeout(int ms, std::string def_value)
{
    struct pollfd fds;
    fds.fd = STDIN_FILENO;
    fds.events = POLLIN;

    int ret = poll(&fds, 1, ms);

    std::string val;
    if (ret > 0 && ((fds.revents & POLLIN) != 0)) {
        //cout << "has data" << endl;
        std::getline(std::cin, val);
    } else {
        //cout << "timeout / no data" << endl;
        val = def_value;
    }
    return val;
}

#include <iostream>
#include <string>

#include <poll.h>
#include <unistd.h>

std::string getline_timeout(int ms, std::string def_value);

int main(int argc, char *argv[])
{   
    std::cout << "What's your name ? " << std::flush;

    // Ask for the name
    std::string mystr = getline_timeout(5000, "John Doe");

    std::cout << "Hello " << mystr << std::endl;
    std::cout << "What is your favorite team ? " << std::flush;

    // Ask for the team
    mystr = getline_timeout(5000, "Gryffindor");

    std::cout << "I like " << mystr << " too!" << std::endl;

    return 0;
}
thibsc
  • 3,747
  • 2
  • 18
  • 38
0

The API getline() can not do what you want. There are two way you can try: - multi thread can work - single thread with multiplexing IO like select/poll/epoll/iocp

In fact, they work same : setting a timer and wait for I/O input or timeout.

tyChen
  • 1,404
  • 8
  • 27