2013-08-17 10 views
5

Wir wissen, Eingabefunktion oder Operator (cin, scanf, bekommt .... Etc) warten, um Eingabeformular Benutzer & diese Zeit hat keine Begrenzung.Wie wird die Eingabeanweisung nach einiger Zeit deaktiviert?

Jetzt werde ich eine Frage stellen & Benutzer geben die Antwort, bis jetzt gibt es kein Problem, aber mein Problem ist "Benutzer hat eine Zeit (kann 30 oder 40 Sekunden), um die Eingabe zu geben, wenn er scheitert dann Eingabe Anweisung wird Automatisch deaktiviert & Nächste Anweisung ausführen. "

Ich denke, Sie bekommen mein Problem. Dann hilf mir bitte in dieser Situation. Es wird besser sein, wenn mir jemand wirklich funktionierenden Beispielcode gibt.

Ich benutze codebolck 12.11 in Windows 7.

+4

Der Standard C++ hat nichts, Ihnen zu helfen. Sie müssen einige mehr oder weniger böse OS-spezifische Tricks anwenden. –

+1

danke für Ihre Antwort. Können Sie mir bitte ein Beispiel oder eine Funktion geben? – Xplosive

+0

Nein, weil ich nicht weiß, was Ihr Betriebssystem ist. –

Antwort

10

Ein Ansatz für * IX'ish Systeme (einschließlich Cygwin unter Windows):

Sie alarm() verwenden könnte eine SIGALRM zu planen, dann read(fileno(stdin), ...) verwenden.

Wenn das Signal read() kommt mit -1 zurückkommen werden und errno-EINTR gesetzt hatte.

Beispiel:

#define _POSIX_SOURCE 1 

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <signal.h> 
#include <errno.h> 

void handler_SIGALRM(int signo) 
{ 
    signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */ 

    /* Do nothing. */ 
} 

int main() 
{ 
    /* Override SIGALRM's default handler, as the default handler might end the program. */ 
    { 
    struct sigaction sa; 
    memset(&sa, 0, sizeof(sa)); 

    sa.sa_handler = handler_SIGALRM; 

    if (-1 == sigaction(SIGALRM, &sa, NULL)) 
    { 
     perror("sigaction() failed"); 
     exit(EXIT_FAILURE); 
    } 
    } 

    alarm(2); /* Set alarm to occur in two seconds. */ 

    { 
    char buffer[16] = { 0 }; 

    int result = read(fileno(stdin), buffer, sizeof(buffer) - 1); 
    if (-1 == result) 
    { 
     if (EINTR != errno) 
     { 
     perror("read() failed"); 
     exit(EXIT_FAILURE); 
     } 

     printf("Game over!\n"); 
    } 
    else 
    { 
     alarm(0); /* Switch of alarm. */ 

     printf("You entered '%s'\n", buffer); 
    } 
    } 

    return EXIT_SUCCESS; 
} 

Anmerkung: In dem obigen Beispiel der blockierenden Aufruf zu read() würde auf jede Signal ankommen interupted werden. Der Code, dies zu vermeiden wird als execise dem Leser überlassen ... :-)

2

Eine andere Methode:
können Sie POSIX verwenden select() Funktion (und einige Makros FD_ZERO, FD_SET, FD_ISSET), die Datei zu überprüfen Deskriptoren (Deskriptor-Nummer 0, dh stdin, in diesem Fall) sind bereit, in einem gegebenen Zeitintervall gelesen zu werden. Wenn sie bereit sind, verwenden Sie die entsprechende Funktion, um die Daten zu lesen (scanf() in diesem Fall).
Dieser Code könnte Ihnen helfen, zu verstehen, was ich sagen will:

#include <sys/select.h> 
#include <sys/time.h> 
#include <stdio.h> 

#define STDIN 0 // Standard Input File Descriptor 
int main() 
{ 
    fd_set input;  // declare a "file descriptor set" to hold all file descriptors you want to check 
    int fds, ret_val, num; // fds: Number of file descriptors; 

    struct timeval tv;  // structure to store Timeout value in the format used by select() function 
    unsigned int timeout = 5; // Your timeout period in seconds 

    tv.tv_sec = timeout;  
    tv.tv_usec = 0; 

    fds = STDIN + 1;   // Set number of file decriptors to "1 more than the greatest file descriptor" 
       // Here, we are using only stdin which is equal to 0 

    FD_ZERO(&input);  // Initialize the set with 0 
    FD_SET(STDIN, &input);  // Add STDIN to set 

    printf("Enter a number within %d secs\n", timeout); 
    ret_val = select(fds, &input, NULL, NULL, &tv); 
       // We need to call select only for monitoring the "input file descriptor set" 
       // Pass rest of them as NULL 

    if (ret_val == -1)   // Some error occured 
     perror("select()"); 
    else if (ret_val > 0)  // At least one of the file descriptor is ready to be read 
    { 
//  printf("Data is available now.\n"); 
     if(FD_ISSET(0, &input))  // Check if stdin is set, here its not necessary as we are using STDIN only 
       // So ret_val>0 means STDIN is raedy to read 
     { 
      scanf("%d", &num); 
     } 
    } 
    else 
     printf("No data within five seconds.\n"); // select returns zero on timeout 

    return 0; 
} 

Mehr Hilfe: select(2)

Sie auch poll() Funktion, die bei Verwendung von (wieder eine POSIX-Standard-Funktion) versuchen können, wie eine Alternative zu wählen(). Siehe poll() & poll(2)

+3

Ich wollte nur den gleichen Vorschlag machen. (Manchmal möchten Sie vielleicht EINTR bei der 'ret_val == -1 'Klausel behandeln.) Um dies auf Windows zu portieren, werfen Sie einen Blick auf diese Frage: http://Stackoverflow.com/q/933745/1025391 – moooeeeep

+0

Danke @moooeeeep für den Link !! Ich habe mich auch gefragt, wie ähnlicher Code unter Windows-basierten Systemen funktionieren kann. Ich habe vergessen, diese Nicht-Portabilität in meiner Antwort zu erwähnen. –

+1

#include #include mein Compiler kann solche der Header-Datei nicht finden. Ich benutze Codeblock 12.11 – Xplosive

0
#include <cstddef> 
#include <ctime> 
#include <iostream> 
#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() 
{ 
char buffer[512] = {0}; 

if (!get_input (buffer, 512, 5)) { 
std::cout<<"Input timed out\n"; 
buffer[0] = '\n'; 
} 

std::cout<<"input: \""<< buffer <<"\"\n"; 
} 
+1

versuchen dieses Programm funktioniert gut – Akshay

+0

Ich führe diesen Code in Code-Blöcke 13.2 es funktioniert gut nach einiger Zeit das Programm endet automatisch mit diesem Code ist es möglich, es für cin ??? – Akshay

+0

Dieser Code verwendet nicht Standard-C, Nicht-POSIX-Funktionalität und ist daher nicht portabel. – alk