Running a timer while other commands are being executed c++

空扰寡人 提交于 2021-01-28 16:32:55

问题


So I am trying creating a proof of concept for a bigger project. I am currently working on a timed quiz, that has only 1 question, and you have 10 seconds to answer.

What im really asking

  • I know I can read the users input by doing

    "cin << Var" or "Var = _getch()"

  • and I can make a timer by doing

    clock_t timer;

    timer = clock();

    //Code

    timer = clock() - t;

  • But how do you put that all together? can you have a timer running while it's asking for input? It doesn't seem like it would, since c++ goes line by line executing each part and waiting until its done before moving on. But there has to be a way! Here is what i have came up with...

    bool Question(int Correct) {
        int Answer = 0;
        cin >> Answer;
        if (Answer == Correct) {
            return true;
        }
        else {
            return false;
        }
    }
    
    int main() {
    
    cout << "1 + 1 is: ";
    
    clock_t Timer;
    Timer = clock();
    
    bool Is_Correct = Question(2);
    
    Timer = clock() - Timer;
    
    cout << "You Answered: ";
    
    if (Is_Correct) {
        cout << "Correct!";
    }
    else {
        cout << "Wrong!";
    }
    
    cout << "\nAnd by the way, you answered the question with " << 10 - (Timer / CLOCKS_PER_SEC) << " Seconds to Spare.\n";
    
    cin.get();
    cin.get();
    
    return 0;
    }
    

Sorry about the spacing, it got kinda messed up.


回答1:


The clock continues running while a program's waiting for input, so there's no problem timing an input operation (i.e. to see how long it took). But if you want to abort the input operation when 10 seconds have lapsed, then you'd have to use platform-specific means, such as keyboard polling. All standard C++ input operations are blocking. So with only standard C++ you could attempt to put the input operation it in its own thread of execution, reasoning that asynchronous, that's what threads are for. But then you'd discover that there's no way to terminate that thread while it's waiting for input, and (getting creative) no way to post faux input to it.

Still, regarding

can you have a timer running while it's asking for input?

if you mean to have a running display of time, why, that's no problem.

You can just put that in its own thread.

However, if you want input of more than a single character per line, then you will probably have to use system-specific means, because with the standard library's facilities for text display modification (which essentially consists of the ASCII \b and \r controls) any way to do it that I can think of messes up the text cursor position each time the displayed time is changed, as exemplified below:

#include <atomic>
#include <chrono>
#include <exception>    // std::terminate
#include <iostream>
#include <iomanip>      // std::setw
#include <thread>
using namespace std;

auto fail( string const& s )
    -> bool
{ cerr << "!" << s << "\n"; terminate(); }

auto int_from( istream& stream )
    -> int
{
    int x;
    stream >> x || fail( "Input operation failed" );
    return x;
}

namespace g {
    atomic<bool>    input_completed;
}  // namespace g

void count_presentation( string const& prompt )
{
    for( int n = 1; not g::input_completed; ++n )
    {
        string const count_display = to_string( n );
        string const s = count_display + prompt.substr( count_display.length() );
        cout << "\r" << s << flush;

        using namespace std::chrono_literals;
        this_thread::sleep_for( 100ms );
    }
}

auto main()
    -> int
{
    string const prompt = string( 20, ' ' ) + "What's 6*7? ";
    auto counter = thread( count_presentation, ref( prompt ) );
    const int x = int_from( cin );
    g::input_completed = true;
    counter.join();
    cout << x << "\n";
}



回答2:


I found this Clock In C++ Console?. It is cool and it answers your question. The author uses gotoxy() to move to the beginning of the console output and overwrite the current time. However I don't recommend the routine of using namespace std; So I edited the code. Good luck with integrating this with yours

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

// to move back to the beginning and output again
void gotoxy (int x, int y)
{
    COORD coord; // coordinates
    coord.X = x; coord.Y = y; // X and Y coordinates
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); // moves to the coordinates
}

int main ()  
{
    std::time_t now;
    while (true)
    {
        gotoxy (0,0);
        now = std::time(0);
        std::cout << "The time is now: " << std::ctime(&now);
        Sleep (20);
   }
    std::cin.get();
    return 0;
}



回答3:


Here's a sample using the utilities in <chrono>. You must have access to C++11 for this.

You can easily use this model to adapt it to your code.

#include <iostream>
#include <chrono>

using namespace std::chrono;

int main() 
{   
    int num;

    // start timing
    auto start = steady_clock::now();

    std::cin >> num;

    // stop timing
    auto stop = steady_clock::now();

    // stop - start will give you the time that passed
    std::cout << "It took " 
              << duration_cast<milliseconds>(stop - start).count()
              << " milliseconds!\n";

    std::cin.get();
}   

This will print you the time it took for everything between the declaration of start and the declaration of stop to be executed.
In the duration_cast you can use seconds, microseconds and other.



来源:https://stackoverflow.com/questions/36877961/running-a-timer-while-other-commands-are-being-executed-c

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