Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12

Discussione: [C] scanf con timeout

  1. #1

    [C] scanf con timeout

    Ciao a tutti, mi servirebbe leggere da input, ad es. un intero, con la condizione che se non si inserisce nulla entro un timeout, si andrà avanti con l'esecuzione.

    es. un menù con scelta 0, 1, 2, 3 associato ad un intero
    scanf("%d", &n);

    se non si sceglie entro 10 sec
    n=0;

    p.s. Il programma deve essere in C, deve girare sotto architettura Unix (Ubuntu), e che debbo utilizzare solo librerie standard.

    Come si fa?

  2. #2
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(void) {
    
        fd_set rfds;
        struct timeval tv;
        int retval;
    
       /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(fileno(stdin), &rfds);
    
       /* Wait up to five seconds. */
        tv.tv_sec = 5;
        tv.tv_usec = 0;
    
       retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */
    
       if (retval == -1)
            perror("select()");
       else if (retval)
            printf("Data is available now.\n");
            /* FD_ISSET(0, &rfds) will be true. */
        else
            printf("No data within five seconds.\n");
    
       return 0;
    }

  3. #3
    Originariamente inviato da menphisx
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(void) {
    
        fd_set rfds;
        struct timeval tv;
        int retval;
    
       /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(fileno(stdin), &rfds);
    
       /* Wait up to five seconds. */
        tv.tv_sec = 5;
        tv.tv_usec = 0;
    
       retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */
    
       if (retval == -1)
            perror("select()");
       else if (retval)
            printf("Data is available now.\n");
            /* FD_ISSET(0, &rfds) will be true. */
        else
            printf("No data within five seconds.\n");
    
       return 0;
    }
    A dir la verità proprio non l'ho capita...
    Dov'è la variabile in cui va a finire il valore immesso?
    E perché alla fine del programma compare nella shell quello che ho scritto prima?

  4. #4
    No quello era un'esempio di come settare un timeout sullo stdin

  5. #5
    Originariamente inviato da menphisx
    No quello era un'esempio di come settare un timeout sullo stdin
    Ok

    Mi sai fare un esempio concreto in cui leggo da input un intero nella variabile n, e se scade il tempo n sarà 0 ?

    Ci ho provato col tuo programma ma nn ci sono riuscito

  6. #6
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(void) {
    
        fd_set rfds;
        struct timeval tv;
        int retval;
        char  ch;
    
       /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(fileno(stdin), &rfds);
    
       /* Wait up to five seconds. */
        tv.tv_sec = 5;
        tv.tv_usec = 0;
    
       retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */
    
       if (retval == -1) {
    
            perror("select()");
    
       }
       else if (retval) {
    
            printf("Data is available now.\n");
            if(read(fileno(stdin), &char, 1) != 1){
    
               printf("Errore di lettura\n");
    
            }
    
        }
        else {
    
            printf("No data within five seconds.\n");
    
        }
    
       return 0;
    }
    Dovrebbe leggere un byte dallo stdin, ma non ne sono sicuro.


  7. #7
    Ho risolto! Avevo sbagliato io a fare lo scanf, non passando il puntatore!

    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>

    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>

    int main(void) {

        
    fd_set rfds;
        
    struct timeval tv;
        
    int retval;

       
    /* Watch stdin (fd 0) to see when it has input. */
        
    FD_ZERO(&rfds);
        
    FD_SET(fileno(stdin), &rfds);

       
    /* Wait up to five seconds. */
        
    tv.tv_sec 5;
        
    tv.tv_usec 0;

       
    retval select(1, &rfdsNULLNULL, &tv);
        
    /* Don't rely on the value of tv now! */
       
    int n;
       if (
    retval == -1)
            
    perror("select()");
       else if (
    retval) {
            
    printf("Data is available now.\n");
            
    /* FD_ISSET(0, &rfds) will be true. */
            
    scanf("%d", &n);
         }
        else {
            
    printf("No data within five seconds.\n");
            
    n=0;        
        }
        
    printf("n=%d\n"n);
       return 
    0;


    p.s. ora sorge un altro problema: se ho inserito già dei caratteri ma non ho fatto invio nei 5 secondi, vorrei "svuotare il buffer". Come si può fare?

  8. #8
    Originariamente inviato da cicciox80
    Ho risolto! Avevo sbagliato io a fare lo scanf, non passando il puntatore!

    ....

    p.s. ora sorge un altro problema: se ho inserito già dei caratteri ma non ho fatto invio nei 5 secondi, vorrei "svuotare il buffer". Come si può fare?
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(void) {
    
        fd_set rfds;
        struct timeval tv;
        int retval;
    
       /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(fileno(stdin), &rfds);
    
       /* Wait up to five seconds. */
        tv.tv_sec = 5;
        tv.tv_usec = 0;
    
       retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */
       int n;
       if (retval == -1)
            perror("select()");
       else if (retval) {
            printf("Data is available now.\n");
            /* FD_ISSET(0, &rfds) will be true. */
            scanf("%d", &n);
         }
        else {
    
            printf("No data within five seconds.\n");
    
            /*Svuota il buffer*/
            while(getchar() != '\n);
    
        }
        printf("n=%d\n", n);
       return 0;
    }

  9. #9
    Originariamente inviato da menphisx
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    ........
    ........
        /*Svuota il buffer*/
        while(getchar() != '\n);
    
        }
        printf("n=%d\n", n);
       return 0;
    }
    Però così si blocca finquando non premo invio
    c'è un modo per sapere se ci sono caratteri nel buffer?

  10. #10
    Ma lo fa automaticamente la select.
    Quando ci sono caratteri pronti alla lettura ritorna il file descriptor.
    Quindi se sei nel blocco:
    codice:
    else if (retval) {
            printf("Data is available now.\n");
            /* FD_ISSET(0, &rfds) will be true. */
            scanf("%d", &n);
         }
    Ci sono perforza dei caratteri da leggere.
    Non saprei come svuotare il buffer in altro modo ... non so prova fflush.


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.