Como hago para luego de que pase un tiempo el programa haga lo que le ordene por ejemplo que deje digitar un numero por 60 segundos por ejemplo despues de esos 60 segundos no deje digitar nada y salgo un mensaje que me diga ha excedido su tiempo sera con clock() porque se que sleep puede que no sirva
¿Es un entorno de consola? ¿aplicación de escritorio? ¿usas alguna librería para la interfaz de usuario?
Tu pregunta, así planteada, es demasiado escueta.
Es un programa normal en visual studio lo que trato de hacer es esto
cin>>x /* esto es para que digite algo y lo lea, lo que necesito es
que si se pasan 60 segundos y no ha digitado nada salga el
mensaje de que ha excedido su tiempo y ya siga con lo que
hay abajo de esta linea como por ejemplo*/
if x==w printf("ha ganado");
podrías crear un thread para escribir y un thread para contar el tiempo, en que estas, windows o linux?
también puedes cojer el reloj del PC y con un bucle ir comprobando si pasaron más de 60 segundos
Cita de: Stakewinner00 en 14 Julio 2014, 23:10 PM
podrías crear un thread para escribir y un thread para contar el tiempo, en que estas, windows o linux?
también puedes cojer el reloj del PC y con un bucle ir comprobando si pasaron más de 60 segundos
estoy en windows entonces pero con un bucle como?
Cita de: Juan821 en 15 Julio 2014, 20:19 PM
estoy en windows entonces pero con un bucle como?
la librería estándar de C++ no dispone de métodos que permitan una lectura no bloqueante sobre el buffer de entrada.
La opción sería crear una tarea con un hilo secundario que se encargase de realizar la lectura... en el hilo principal pones una espera activa hasta que pase el tiempo o el usuario introduzca un valor.... si se produce el timeout entonces matas el hilo secundario. Si antes de acabar el tiempo el usuario introduce un valor entonces dejas que el usuario introduzca su valor con normalidad y el programa continua.
Cita de: Juan821 en 9 Julio 2014, 03:56 AM
Como hago para luego de que pase un tiempo el programa haga lo que le ordene por ejemplo que deje digitar un numero por 60 segundos por ejemplo despues de esos 60 segundos no deje digitar nada y salgo un mensaje que me diga ha excedido su tiempo
Buenas, la unica forma que se me ocurre para lograr eso sin el uso de hilos, es haciendo uso de las funciónes
kbhit() y getche() de la libreria
conio.h #include <iostream>
#include <cstddef>
#include <ctime>
#include <conio.h>
bool get_input ( char *buffer, std::size_t size, int timeout )
{
std::time_t start = std::time ( 0 );
std::size_t n = 0;
for (;;)
{
if ( n == 0 && std::difftime (std::time(0), start ) >= timeout )
return false;
if (kbhit()) {
if ( n == size - 1 )
break;
char ch = (int)getche();
if ( ch == '\r' )
{
buffer[n++] = '\n';
break;
}
else
buffer[n++] = ch;
}
}
buffer[n] = '\0';
return true;
}
int main(void)
{
char buffer[20] = {};
if ( !get_input (buffer, 20, 5) ) {
std::cout << "Tiempo agotado\n";
buffer[0] = '\n';
}
std::cout<<"\nSalida: " << buffer;
return 0;
}
Se que la libreria
conio.h no es recomendable utilizarla
Cita de: Juan821 en 15 Julio 2014, 20:19 PM
...........................estoy en windows ..........................
Pues si estas en Windows podrías usar windows.h para "Sleep" y conio.h para kbhit:
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;
int main(){
int i , ss = 5 , algo = 0 ;
while( !kbhit() ){
for( i = ss ; i>= 0 ; i-- ){
if (kbhit()){
cout << endl;
break;
}
Sleep(1000);
cout << "Quedan: " << setw(2) << i << " segundos.\r" ;
}
if ( i == -1 ) break;
}
if ( i> -1){
cin >> algo;
cout << endl << "algo= " << algo << endl;
}
else cout << endl << "Tiempo excedido\n" << endl;
return 0;
}
Y reitero lo de
kutcher, sí ya sé que no es aconsejable usar conio, pero no se me apetece meterme ahora con las API de Windows. ;)
¡¡¡¡ Saluditos! ..... !!!!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
Cita de: leosansan en 16 Julio 2014, 21:11 PM
Pues si estas en Windows podrías usar windows.h para "Sleep" y conio.h para kbhit:
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;
int main(){
int i , ss = 5 , algo = 0 ;
while( !kbhit() ){
for( i = ss ; i>= 0 ; i-- ){
if (kbhit()){
cout << endl;
break;
}
Sleep(1000);
cout << "Quedan: " << setw(2) << i << " segundos.\r" ;
}
if ( i == -1 ) break;
}
if ( i> -1){
cin >> algo;
cout << endl << "algo= " << algo << endl;
}
else cout << endl << "Tiempo excedido\n" << endl;
return 0;
}
Y reitero lo de kutcher, sí ya sé que no es aconsejable usar conio, pero no se me apetece meterme ahora con las API de Windows. ;)
¡¡¡¡ Saluditos! ..... !!!!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
ya lo probe si sirve pero el problema es que si le dan a una letra y no le dan enter
se pausa la cuenta regresiva he intentando arreglarlo pero no he sido capas aunque muchas gracias que con esto seguire averiguando para perfeccionarlo gracias
Cita de: eferion en 16 Julio 2014, 00:07 AM
la librería estándar de C++ no dispone de métodos que permitan una lectura no bloqueante sobre el buffer de entrada.
La opción sería crear una tarea con un hilo secundario que se encargase de realizar la lectura... en el hilo principal pones una espera activa hasta que pase el tiempo o el usuario introduzca un valor.... si se produce el timeout entonces matas el hilo secundario. Si antes de acabar el tiempo el usuario introduce un valor entonces dejas que el usuario introduzca su valor con normalidad y el programa continua.
¿Puedes brindarnos un ejemplo sencillo y/o alguna pagina/pdf/tutorial o lo que sea sobre el tema?
He leído sobre POSIX no POSIX y la verdad es que menudo lio eso de los trheads y procesos.
Pinta bien pero no veas si raya jejeje.
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.
class DataManager
{
public:
DataManager( ) = default;
DataManager( const DataManager& ) = delete;
~DataManager( ) = default;
void Run( )
{
int temp_number = 0;
while ( true )
{
char c = getch( );
_withData = true;
if ( c != '\n' && c != '\r' )
{
std::cout << c;
temp_number *= 10;
temp_number += c - '0';
}
else
{
std::cout << std::endl;
_number = temp_number;
break;
}
}
}
bool WithData( ) const
{ return _withData; }
int Number( ) const
{ return _number; }
const DataManager& operator=( const DataManager& ) = delete;
private:
bool _withData = false;
int _number = 0;
};
Después necesitamos una clase para llevar de forma sencilla el conteo del tiempo... algo del tipo:
class Timer
{
public:
using milliseconds = std::chrono::milliseconds;
Timer( )
{
Reset( );
}
Timer( const Timer& ) = delete;
~Timer( ) = default;
void Reset( )
{
_start = std::chrono::high_resolution_clock::now( );
}
milliseconds Elapsed( ) const
{
return std::chrono::duration_cast< milliseconds >( std::chrono::high_resolution_clock::now( ) - _start );
}
const Timer& operator=( const Timer& ) = delete;
private:
std::chrono::high_resolution_clock::time_point _start;
};
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:
int main( )
{
std::cout << "Introduce un numero." << std::endl;
std::cout << "Tienes 5 segundos para empezar" << std::endl;
DataManager manager;
std::thread thread{ [](DataManager* mgr){ mgr->Run( ); }, &manager };
Timer timer;
while ( timer.Elapsed( ) < std::chrono::seconds{ 5 } )
{
if ( manager.WithData( ) )
break;
}
if ( !manager.WithData( ) )
thread.detach( );
else
thread.join( );
if ( manager.WithData( ) )
std::cout << "Has introducido el numero: " << manager.Number( ) << std::endl;
else
std::cout << "No has introducido ningun numero." << std::endl;
}
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.
Sin conio.h pero con:
#include <windows.h>
#include <iostream>
#include <iomanip>
#include <unistd.h>
#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 ;)
using namespace std;
void *hilo1(void *X){
int i , ss = 10 ;
cout << "Creando hilo " << endl;
while( 1 ){
for( i = ss ; i>= 0 ; i-=2 ){
Sleep(2000);
cout << " Quedan: " << setw(2) << i << " segundos.\r" ;
}
if ( i == -1 ) break;
}
cout << endl << "Tiempo excedido\n" << endl;
exit(1) ;
}
int main(){
int algo = 0 ;
pthread_t hilo ;
pthread_create (& hilo , NULL , hilo1 , NULL );
cout << endl << "No te olvides del ENTER " << endl;
cin >> algo ;
cout << endl << endl << "algo = " << algo << endl;
return 0;
}
¡¡¡¡ Saluditos! ..... !!!!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)