elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Temporizadores
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: Temporizadores  (Leído 4,489 veces)
eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Temporizadores
« Respuesta #10 en: 18 Julio 2014, 12:49 pm »

No es un mecanismo excesivamente depurado pero sirve para la ocasión:

Lo primero que necesitamos es una clase que nos permita "controlar" la entrada del teclado.

Para nuestra desgracia, el estándar de C++ no ayuda, ya que los mecanismos de entrada no van a devolver ningún dato hasta que el usuario presione la tecla "enter". Por este motivo nos tenemos que pegar con mecanismos menos portables... para la ocasión he usado la tan odiada "conio". Si alguien se lo quiere currar más está en su perfecto derecho.

El método run de la clase es bastante simple... cuando se presiona una tecla, activa un flag que indica la intención del usuario de introducir un número... cuando se introduce un carácter se actualiza el número introducido (esta versión no admite backspace)... cuando se introduce un enter se almacena el número y se sale de la función.

Código
  1. class DataManager
  2. {
  3.  public:
  4.  
  5.    DataManager( ) = default;
  6.  
  7.    DataManager( const DataManager& ) = delete;
  8.  
  9.    ~DataManager( ) = default;
  10.  
  11.    void Run( )
  12.    {
  13.      int temp_number = 0;
  14.  
  15.      while ( true )
  16.      {
  17.        char c = getch( );
  18.        _withData = true;
  19.  
  20.        if ( c != '\n' && c != '\r' )
  21.        {
  22.          std::cout << c;
  23.          temp_number *= 10;
  24.          temp_number += c - '0';
  25.        }
  26.        else
  27.        {
  28.          std::cout << std::endl;
  29.          _number = temp_number;
  30.          break;
  31.        }
  32.      }
  33.    }
  34.  
  35.    bool WithData( ) const
  36.    { return _withData; }
  37.  
  38.    int Number( ) const
  39.    { return _number; }
  40.  
  41.    const DataManager& operator=( const DataManager& ) = delete;
  42.  
  43.  private:
  44.  
  45.    bool _withData = false;
  46.    int _number = 0;
  47. };

Después necesitamos una clase para llevar de forma sencilla el conteo del tiempo... algo del tipo:

Código
  1. class Timer
  2. {
  3.  public:
  4.    using milliseconds = std::chrono::milliseconds;
  5.  
  6.    Timer( )
  7.    {
  8.      Reset( );
  9.    }
  10.  
  11.    Timer( const Timer& ) = delete;
  12.  
  13.    ~Timer( ) = default;
  14.  
  15.    void Reset( )
  16.    {
  17.      _start = std::chrono::high_resolution_clock::now( );
  18.    }
  19.  
  20.    milliseconds Elapsed( ) const
  21.    {
  22.      return std::chrono::duration_cast< milliseconds >( std::chrono::high_resolution_clock::now( ) - _start );
  23.    }
  24.  
  25.    const Timer& operator=( const Timer& ) = delete;
  26.  
  27.  private:
  28.    std::chrono::high_resolution_clock::time_point _start;
  29. };

Cuando se crea la clase se registra el tiempo y llamando a "Elapsed" se devuelve el número de milisegundos desde ese instante. Reset vuelve a inicializar la clase.

Con estos ingredientes ya tenemos casi todo el trabajo echo... solo nos falta mezclarlos convenientemente en el main:

Código
  1. int main( )
  2. {
  3.  std::cout << "Introduce un numero." << std::endl;
  4.  std::cout << "Tienes 5 segundos para empezar" << std::endl;
  5.  
  6.  DataManager manager;
  7.  
  8.  std::thread thread{ [](DataManager* mgr){ mgr->Run( ); }, &manager };
  9.  
  10.  Timer timer;
  11.  while ( timer.Elapsed( ) < std::chrono::seconds{ 5 } )
  12.  {
  13.    if ( manager.WithData( ) )
  14.      break;
  15.  }
  16.  
  17.  if ( !manager.WithData( ) )
  18.    thread.detach( );
  19.  else
  20.    thread.join( );
  21.  
  22.  if ( manager.WithData( ) )
  23.    std::cout << "Has introducido el numero: " << manager.Number( ) << std::endl;
  24.  else
  25.    std::cout << "No has introducido ningun numero." << std::endl;
  26. }

Para controlar la entrada del teclado se crea un hilo. Después se inicializa el temporizador y se mantiene una espera activa de 5 segundos. La idea del temporizador en vez de un sleep es para que la aplicación pueda responder instantáneamente si el usuario introduce el número antes de 5 segundos.

Pasado el tiempo de espera activa se comprueba si el usuario ha hecho al menos el amago de introducir un número... si es así entonces espera pacientemente a que el usuario termine de introducir el número... en caso contrario finaliza el hilo y muestra el mensaje correspondiente.

Como he comentado antes, es algo muy mejorable. El ejemplo lo he realizado a petición de vangodp y sirve solo con fines ilustrativos.

PD.: utiliza funciones propias de C++11, ojo con los compiladores no compatibles.


En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Temporizadores
« Respuesta #11 en: 18 Julio 2014, 16:56 pm »

Sin conio.h pero con:

Código
  1. #include <windows.h>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <unistd.h>
  5. #include <pthread.h>

Creo un hilo para el contador, que sigo usando Sleep por ganseria en lugar de cronos, y poco más. Sólo que el "Quedan" podemos evitarlo ya que distorsiona un poco la impresión. Pero bueno, como intento sin usar conio y que no espere hasta que se dé al ENTER creo que vale.....y ojo que no soy especialista en hilos, así que las críticas suaves, please  ;)

Código
  1. using namespace std;
  2.  
  3. void *hilo1(void *X){
  4.  int i , ss = 10 ;
  5.  cout << "Creando hilo " << endl;
  6.  while( 1 ){
  7.    for( i = ss ; i>= 0 ; i-=2 ){
  8.      Sleep(2000);
  9.    cout << "   Quedan: " << setw(2) << i << " segundos.\r"  ;
  10.    }
  11.    if ( i == -1 ) break;
  12.  }
  13.  cout << endl << "Tiempo excedido\n" << endl;
  14.  exit(1) ;
  15. }
  16.  
  17. int main(){
  18.  int  algo = 0 ;
  19.  pthread_t hilo ;
  20.  pthread_create (& hilo , NULL , hilo1 , NULL );
  21.  cout << endl << "No te olvides del ENTER " << endl;
  22.  cin >> algo ;
  23.  cout << endl << endl << "algo = " << algo << endl;
  24.  return 0;
  25. }

¡¡¡¡ Saluditos! ..... !!!!




« Última modificación: 18 Julio 2014, 17:17 pm por leosansan » En línea

Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Aporte] Temporizadores con cuenta atrás desde una Fecha [PHP]
PHP
z3nth10n 0 2,353 Último mensaje 16 Agosto 2013, 13:09 pm
por z3nth10n
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines