Witam.
Czy da się zrobić w zwykłym C++ tak, aby pobierał wartość przez dany czas?
Np "cin" przez 40 sekund
Najprawdopodobniej będziesz musiał użyć wątków (wielowątkowość, sprawdź std::thread), ponieważ std::cin oczekuje na input z klawiatury, dopóki nie zatwierdzisz inputu, nic się nie "ruszy" z kodem po std::cin. Dodatkowy wątek umożliwi wykonywanie dodatkowego kodu, który umożliwi np wyświetlenie informacji o timeoucie po 40 sekundach.
Edit: Ja subiektywnie przeczuwam, że w jest duża szansa, że da się Twój problem rozwiązać w inny sposób. Dobrze by było abyś powiedział nam co konkretnie chcesz osiągnąć.
Chodzi mi o to, że ktoś dostaje pytanie i ma np 40 sekund na odpowiedź i jak nie odpowie w ciągu 40 sekund to przestaje pobierać z klawiatury
Niewykonalne jest z tego co wiem zatrzymanie inputu z poziomu konsoli z std::cin bez naciśnięcia po prostu enter. (https://www.quora.com/How-do-I-stop-reading-a-string-in-C++-when-a-condition-is-met)
Możesz co prawda nie zatrzymywać inputu, a jednak w dodatkowym wątku napisać po 40 sekundach, coś w stylu "Koniec czasu na pytanie" i spowodować, że ta zmienna która i tak zostanie pobrana nie będzie uwzględniona,
Lepszym sposobem byłoby wykorzystanie jakiejś biblioteki do GUI i tam zrobienie czegoś takiego.
W takim przypadku prawdopodobnie chcesz skorzystać z nieprzenośnych api systemowych, a nie blokującego pobierania. Narzędzia dostępne w bibliotece standardowej na to nie pozwalają.
Jeżeli chodzi ci o zrobienie quizu z timeoutem, to imo prościej jest zrobić tak, że w momencie wyświetlenia pytania zapamiętujesz czas i sprawdzasz różnicę między czasem który zapamiętałeś w momencie zadania pytania a tym w momencie odpowiedzi. Jeżeli różnica wynosi ponad 40 sekund no to sobie tam handlujesz jakoś wejście na zasadzie "Odpowiedź po czasie" czy cośtam, niezależnie od tego co użytkownik wprowadził.
IMO nie ma co kombinować.
W pytaniu napisać o limicie czasowym, grzecznie czekać na odpowiedź, zmierzyć czas odpowiedzi i napisać, potem "prawidłowa odpowiedź, ale przekroczyłeś limit czasowy".
Jeśli chcesz się bawić w wątki (odradzam) to można "wyświetlić" upływ czasu, ale cały czas czekać na odpowiedź.
Zresztą wykorzystanie stdin i stdout do takiego zadania, to kiepski pomysł, lepiej użyć ncurses
.
Masz tu prostą implementację asynchronicznego odczytu:
#include <iostream>
#include <chrono>
#include <future>
#include <string>
int main()
{
std::string line;
auto future = std::async(std::launch::async, [&line]() {std::cin.get(); });
if (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready)
{
std::cout << "koniec czasu" << line << std::endl;
}
else
{
//sprawdz czy w "line" znajduje sie poprawna odpowiedz
}
}
Złą wiadomością jest to, że std::cin będzie czekał na jakiś input, a co za tym idzie wątek się nie zakończy. Dobrą wiadomością jest to że możesz symulować wciśniecie entera. Jeśli korzystasz z Windowsa to będzie wyglądało tak:
#include <windows.h>
void VirtualKeyPress()
{
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wVk = VK_RETURN;
ip.ki.dwFlags = 0;
SendInput(1, &ip, sizeof(INPUT));
}