2012-03-19 11 views
5

Sto provando a scrivere una simulazione che continuerà a funzionare fino a quando non premo un tasto (come 'q' per uscire). Poi, dopo averlo premuto, voglio che il programma finisca di scrivere i dati in corso di scrittura, chiudere i file, quindi uscire con grazia (anziché premere semplicemente ctrl + c per forzare il programma a fermarsi). C'è un modo per farlo in C++?"Sicuro" termina un programma C++ in esecuzione su Keypress?

Grazie

+0

C'è sicuramente un modo per farlo. Avrai bisogno di uscire dai tuoi loop di simulazione in qualche modo, ma rilevare il keypress sarà il kicker. Su quale sistema operativo verrà eseguito questo sistema operativo? – djdanlib

+3

Sembra una domanda piuttosto ampia. 1) Come leggo una chiave in modo asincrono? 2) Come posso avvisare il programma di spegnersi? 3) Come assicurarsi che tutti i dati siano scritti prima di finalizzare l'arresto? – Almo

+0

Questo verrà eseguito su linux o mac. Preferibilmente mi piacerebbe che fosse non dipendente dal sistema operativo, ma se è l'unica opzione allora qualcosa di unix compatibile. Fondamentalmente speravo che ci fosse un modo per "ascoltare" un keypress in modo che alla fine di ogni iterazione della simulazione, avrebbe controllato se quel tasto era stato premuto, quindi richiamava una funzione di spegnimento. – Eddy

risposta

5

hanno l'utente stampa CTRL - C, ma installare un gestore di segnale a che fare con esso. Nel gestore di segnale, impostare una variabile booleana globale, ad esempio user_wants_to_quit. Poi il ciclo sim può apparire come:

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

Un programma completo POSIX (scusate, se speravate per Microsoft Windows), compresa l'impostazione e il ripristino del SIGINT (CTRL - C) gestore:

#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

Come si installa il gestore di segnale? – Eddy

+0

@ Eddy - Vedi la mia modifica. –

Problemi correlati