1

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.

Dosisod
  • 307
  • 2
  • 15
  • As a start, this is very C-like! Try using the `` header for time-like utilities. – DeiDei Apr 27 '16 at 00:19
  • @alf Sorry i forgot to mention it will be a windows only. Is there a way the tell the exe that if a command (cin) isn't answered within 10 seconds, it should just "move on" ? – Dosisod Apr 27 '16 at 00:50
  • If you are trying to make a better wheel why not do it properly and use a code profiling tool with visualization. In the HPC community Tuning and Analysis Utilities(TAU) http://www.cs.uoregon.edu/research/tau/home.php is popular. It may seem like full blown instrumentation and profiling is overkill, 1)it will give you the timing information you desire plus more detailed timings, 2) it is good to know how to use this sort of tool, 3) you may not find exactly what you were looking for but you will probably find something interesting with respect to performance bottlenecks in the process – Matt Apr 27 '16 at 00:52

3 Answers3

0

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;
}
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
0

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.

DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • Yes, so I can get the time it took for you to type in an input. But is there a way for the program to stop waiting for an input and just say "Times up!" ? – Dosisod Apr 27 '16 at 00:58
0

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";
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Ok so in windows? C++11 – Dosisod Apr 27 '16 at 01:02
  • @Dosisod: If you mean, what system specific means are there in Windows? Then, Windows has a difficult-to-use-correctly console window API. But you can use the ncurses library also in Windows. Simpler, if your compiler supports it, there's a non-standard header called `conio.h` that supports keyboard polling. And for a GUI Windows offers both timer messages, and hard thread timers. – Cheers and hth. - Alf Apr 27 '16 at 01:21
  • Thank you for the help! I found a thread that can wait for keyboard input and still run a timer : http://stackoverflow.com/questions/14192230/wait-for-input-for-a-certain-time – Dosisod Apr 27 '16 at 05:22