2012-03-19 12 views
5

Estoy tratando de escribir una simulación que continuará ejecutándose hasta que presione cierta tecla (como 'q' para salir). Luego, después de presionar eso, quiero que el programa termine de escribir los datos que está escribiendo actualmente, cierre los archivos, luego salga con gracia (en lugar de presionar ctrl + c para forzar al programa a detenerse). ¿Hay alguna manera de hacer esto en C++?"de forma segura" ¿finaliza un programa C++ en ejecución al presionar teclas?

Gracias

+0

Sin duda hay una forma de hacerlo. Tendrás que salir de los bucles de simulación de alguna manera, pero detectar la pulsación de tecla va a ser el golpeador. ¿En qué sistema operativo se ejecutará este programa? – djdanlib

+3

Parece una pregunta bastante amplia. 1) ¿Cómo leo una clave de forma asíncrona? 2) ¿Cómo notifico el cierre del programa? 3) ¿Cómo asegurarse de que se escriben todos los datos antes de finalizar el cierre? – Almo

+0

Esto se ejecutará en linux o mac. Preferiblemente me gustaría que no dependa del os, pero si es la única opción, entonces algo compatible con Unix. Básicamente, esperaba que hubiera una forma de "escuchar" una pulsación de tecla para que, al final de cada iteración de la simulación, comprobara si se había presionado esa tecla, y luego llamaba a una función de apagado. – Eddy

Respuesta

5

que el usuario presione CTRL - C, pero instalar un manejador de señales para tratar con él. En el controlador de señal, establezca una variable booleana global, por ejemplo user_wants_to_quit. A continuación, el bucle sim puede verse como:

while (work_to_be_done && !user_wants_to_quit) { 
… 
} 
// Loop exited, clean up my data 

Un programa completo POSIX (lo siento, si usted estaba esperando para Microsoft Windows), incluyendo el establecimiento y la restauración de la SIGINT (CTRL - C) manejador:

#include <iostream> 
#include <signal.h> 

namespace { 
    sig_atomic_t user_wants_to_quit = 0; 

    void signal_handler(int) { 
    user_wants_to_quit = 1; 
    } 
} 

int main() { 

    // Install signal handler 
    struct sigaction act; 
    struct sigaction oldact; 
    act.sa_handler = signal_handler; 
    sigemptyset(&act.sa_mask); 
    act.sa_flags = 0; 
    sigaction(SIGINT, &act, &oldact); 


    // Run the sim loop 
    int sim_loop_counter = 3; 
    while((sim_loop_counter--) && !user_wants_to_quit) { 
    std::cout << "Running sim step " << sim_loop_counter << std::endl; 

    // Sim logic goes here. I'll substitute a sleep() for the actual 
    // sim logic 
    sleep(1); 

    std::cout << "Step #" << sim_loop_counter << " is now complete." << std::endl; 
    } 

    // Restore old signal handler [optional] 
    sigaction(SIGINT, &oldact, 0); 

    if(user_wants_to_quit) { 
    std::cout << "SIM aborted\n"; 
    } else { 
    std::cout << "SIM complete\n"; 
    } 

} 
+0

¿Cómo se instalaría el controlador de señal? – Eddy

+0

@Eddy - Ver mi edición. –

Cuestiones relacionadas