How to use a timer in C++ to force input within a given time?

时光怂恿深爱的人放手 提交于 2019-11-26 12:47:25

问题


I want to implement a time out feature in C++.

If the user does not input the value within 2 seconds then the program must display the time-out statement and ask the input again

EX(OUTPUT SCREEN):

Timer=0;  
Please enter the input:       //if input is not given within 2 seconds then  
Time-out: 2 seconds  
Timer again set to 0  
Please enter the input:  //if input is not given within 2 seconds then  
Time-out: 2 seconds  
Timer again set to 0  
Please enter the input:22  
Data accepted  
Terminate the program`

Code:

#include<iostream>  
 #include<time.h>  
 using namespace std;  
 int main()  
{  
    clock_t endwait;  
    endwait =  2000 ;  
   cout<<endwait;  
   while (clock() < endwait)  
  {  
         cout<<\"Please enter the input:\";  
  }  
   return 0;  
} 

I have worked on the above code. But this happens only while entering the WHILE loop. How shall i do it in a way so that, I get the required output.


回答1:


#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
using namespace std;
condition_variable cv;

int value;

void read_value() {
    cin >> value;
    cv.notify_one();
}

int main()
{
    cout << "Please enter the input: ";
    thread th(read_value);

    mutex mtx;
    unique_lock<mutex> lck(mtx);
    while (cv.wait_for(lck, chrono::seconds(2)) == cv_status::timeout)
    {
        cout << "\nTime-Out: 2 second:";
        cout << "\nPlease enter the input:";
    }
    cout << "You entered: " << value << '\n';

    th.join();

    return 0;
}

Output:

Please enter the input:  
Time-Out: 2 second:  
Please enter the input:  
Time-Out: 2 second:  
Please enter the input:22  
You entered: 22  



回答2:


I am afraid, it is not possible in a standard way because I/O operations will block, by default, the calling process until it's finalized or an error is encountered.
You could work it around by creating a thread which checks whether the input has been completed and go sleeping, if needed. But that's not really practical.

The issue lies in the abstraction iostream/FILEs give you: you don't have access to the underlying source, the one the OS "understands" as well and therefore capable to give you that kind of functionality (namely, I/O polling).




回答3:


A separate thread is not enough, because the console read function is still running after the timeout occurs.

On POSIX you could set a timer which produces a signal and causes the read to fail with -EINTR.

On Windows you can implement low-level console I/O timeouts with ReadConsoleInput and WaitForSingleObject... but then you need to do your own line-buffering.

Another idea would be to use ReadFile in OVERLAPPED mode and wait on the completion event with a timeout, but that doesn't work for consoles, see Using overlapped IO for console input?

Finally, new Windows versions (Vista and later) allow you to overcome the "blocking read is not cancelled by timeout" problem using CancelIoEx. If you call that from a separate thread, it will trigger ReadFile to return early; you won't have to implement line-buffering yourself.




回答4:


I think there is no need to use complex code (multithreading or mutex) for this purpose. See the code below :

#include <iostream>
#include <time.h>
#include <conio.h>

using namespace std;

int main()
{
    int numInput;

    clock_t start = clock();

    cout << "Timer: 2 sec"<<endl;

    cout << "Please enter the input: ";

    while ( ! _kbhit() ) //Check for keyboard hit
    {
        //Check if 2 sec timer expired or not
        if (((clock () - start)/ CLOCKS_PER_SEC ) >= 2) 
        {
            cout << "\nTimeout  2 sec . . ." << endl;
            cout << "Please enter the input: ";
            start = clock();                            //Set new timer
        }
    }

    //Get the input here
    cin >> numInput;

    cout << "Data accepted: " << numInput << endl;

    _getch();

    return 0;
}



回答5:


I have used kbhit() function to solve your problem. The code is as follows:-

    #include <conio.h>
    #include <iostream>
    #include <windows.h>

    using namespace std;

    int main()
    {
        int i;
        DWORD start_time, check_time;
        start_time=GetTickCount();
        check_time=start_time+2000;
        while(!kbhit())
        {
            cout<<"Please enter the input:"<<endl;
            while((check_time>GetTickCount()))
            {
                if (kbhit())
                {
                    i=getch();
                    cout<<"Data accepted"<<endl;
                    return 0;
                }
            }
            cout<<"Time-out: 2 seconds"<<endl;
            cout<<"Timer again set to 0"<<endl;
            start_time=GetTickCount();
            check_time=start_time+2000;
        }
    return 0;

    }


来源:https://stackoverflow.com/questions/28944972/how-to-use-a-timer-in-c-to-force-input-within-a-given-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!