It's not that hard to do. If you're on windows you can use the conio.h functions. On linux you can emulate them like this:
Code:
// g++ -std=c++11 -Wall -o timeit timeit.cpp -pthread
#define _BSD_SOURCE // for cfmakeraw
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>
struct termios orig_termios;
void reset_terminal_mode() {
tcsetattr(0, TCSANOW, &orig_termios);
}
void set_conio_terminal_mode() {
struct termios new_termios;
tcgetattr(0, &orig_termios);
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
cfmakeraw(&new_termios);
tcsetattr(0, TCSANOW, &new_termios);
}
int kbhit() {
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return select(1, &fds, NULL, NULL, &tv);
}
int getch() {
int r;
unsigned char c;
if ((r = read(0, &c, 1)) < 0)
return r;
write(1, &c, 1);
return c;
}
#include <iostream>
#include <string>
#include <future>
#include <chrono>
int main() {
std::string name{};
auto tp = std::chrono::system_clock::now() + std::chrono::seconds(5);
std::atomic<bool> keep_reading(true);
std::future<void> f =
std::async(std::launch::async, [&name, &keep_reading]() {
char s[100], *p = s;
std::cout << "enter your name \n";
set_conio_terminal_mode();
for (int i = 0; keep_reading; ) {
if (kbhit()) {
int c = getch();
if (++i == sizeof s || c < 0 || c == '\r') {
c = '\n';
write(1, &c, 1);
*p = '\0';
name = s;
break;
}
*p++ = c;
}
// You might want to add a millisecond or so of sleep here
// so the busy wait is not so cpu intensive.
}
reset_terminal_mode();
});
std::future_status s = f.wait_until(tp);
if (s == std::future_status::ready) {
f.get();
std::cout << "well in time, your name is: " << name << "\n";
}
else {
keep_reading = false;
std::cout << "\ntook too long, enter first name now\n";
getline(std::cin, name);
std::cout << "name is: " << name << "\n";
}
return 0;
}