Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305

    [C] Differenza tra getch() e getchar()

    Salve vorrei capire meglio la differenza tra queste due funzioni , anche se una è ansi e l'altra no. Ho capito fin ora che getch() a differenza di getchar() non esegue l'eco su stdoutput, ma non ho capito bene la differenza sul fatto che una non è bufferizzata e l'altra si. Potreste spiegarmi meglio questa cosa.

    Tratto da Programmare in c:
    Alcune funzioni dispongono di un buffer dove il sistema operativo memorizza tutti i caratteri finchè l'utente non preme invio per inviarli al flusso stdin. Altre sono prive di buffer, quindi ogni carattere è inviato a stdin non appena viene premuto il tasto corrispondente.

    Adesso mi chiedo ma se io gia leggo da stdin quando uso la tastiera com'è che qui dice inviare a stdin?
    Ultima modifica di linux_r; 09-05-2014 a 20:37

  2. #2
    Quote Originariamente inviata da linux_r Visualizza il messaggio
    Tratto da Programmare in c:
    Alcune funzioni dispongono di un buffer dove il sistema operativo memorizza tutti i caratteri finchè l'utente non preme invio per inviarli al flusso stdin. Altre sono prive di buffer, quindi ogni carattere è inviato a stdin non appena viene premuto il tasto corrispondente.

    Adesso mi chiedo ma se io gia leggo da stdin quando uso la tastiera com'è che qui dice inviare a stdin?
    Una descrizione dettagliata di cosa succede realmente all'interno di un comune PC al momento della pressione di un tasto richiede diverse dozzine di pagine, anche restando ad un livello puramente software/firmware e limitandoci alla più ordinaria delle connessioni fisiche. Tra controller della tastiera, BIOS e relativa area dati, interrupt, RAM, CPU, sistema operativo, librerie e software applicativo vario i codici coinvolti (inizialmente scancode e release code, poi il codice ASCII o altra codifica adottata...) compiono un vero e proprio viaggio prima di essere messi a disposizione del programmatore e/o dell'utente, tipicamente sotto forma di pixel a video in quest'ultimo caso.

    Pur nella impossibilità di elencare qui i vari passaggi, si tenga presente che il file speciale denominato stdin è ovviamente parte di codesta complessa catena (che è descritta in numerosi testi specifici e che qualsiasi programmatore dovrebbe conoscere, almeno per sommi capi), ma ne è una parte terminale, a monte della quale vi sono numerosi passaggi.
    Sui sistemi DOS (ancor oggi, ad esempio su PC industriali e sistemi PC-104 con SO DOS compatibili) era prassi assolutamente comune intercettare lo stato dei tasti speciali, dei LED e degli switch a livello di BIOS data area e intervenire direttamente sulla codifica "al volo" dei tasti a livello di interrupt, con un compatto TSR, ad esempio per filtrare le lettere accentate sostituendole con digrafi (es. à->a') come richiesto dai mailer FIDOnet e da quasi ogni programma di comunicazione basato su ASCII-7, e più in generale per avere il massimo controllo sull'input nei programmi CLI e SAA/CUA.

    Le implementazioni di libreria della funzione non standard getch(), che proprio in quegli anni si è affermata come standard de facto nel mondo dei PC DOS grazie alle prime implementazioni proprietarie dovute a Borland, lavorano normalmente ad un livello più basso e meno "portabile" rispetto alla generica ma limitatagetchar().
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    ti ringrazio della risposta, su internet ho trovato slide che in modo grossolano ti spiegano quello che avviene nel sistema operativo,in effetti penso che sia quello che mi interessa in grosso modo... per il resto ti ringrazio delle info ma non mi sono utili !

    Si accettano comunque altre risposte meno complesse e che spiegano in grosso modo la bufferizzazione .

  4. #4
    Nulla potrebbe essere più utile ad un programmatore della conoscenza dell'intero processo di acquisizione di un codice tasto!

    Il buffering è solo l'ultima banalità della catena. Se l'input è "buffered", come nel caso generico della getchar(), il tasto o i tasti premuti vengono messi a disposizione del programma solo dopo la pressione di ENTER (invio). Questo implica che la funzione in oggetto:
    1) Sospende il programma, in linea di principio, fino alla pressione di ENTER;
    2) Tutto ciò che viene digitato prima di ENTER viene salvato internamente in un buffer, ovvero un array gestito dalla libreria e/o dal SO.
    3) Quando la funzione termina, essa restituisce il primo valore prelevato dal buffer.
    L'aspetto più importante è che è obbligatorio premere ENTER per terminare l'input.

    Altro aspetto importante, la pulizia del buffer. Lo standard, fin dal C'89, è estremamente chiaro: si tratta di una operazione opzionale. I compilatori non hanno l'obbligo di implementare la fflush() sugli stream di input.
    Per la pulizia del buffer occorre quindi un idioma specifico, come il seguente.

    codice:
    void kbd_clean(void)
    {
        register char ch;
        do 
        {
            ch = getchar();
        } while (('\n' != ch) && (EOF != ch));
        /* 
        ** Alternativamente, piu' in sintesi: 
        ** while ((ch = getchar() != '\n') && (ch != EOF));
        */
    }
    Le funzioni unbuffered, come getch(), non hanno questo genere di problemi e restituiscono direttamente il primo tasto premuto.
    Non accedono ad alcun buffer interno e non richiedono la pressione di tasti specifici. Nulla di particolarmente esotico.
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    Quote Originariamente inviata da M.A.W. 1968 Visualizza il messaggio
    Per la pulizia del buffer occorre quindi un idioma specifico, come il seguente.

    codice:
    void kbd_clean(void)
    {
        register char ch;
        do 
        {
            ch = getchar();
        } while (('\n' != ch) && (EOF != ch));
        /* 
        ** Alternativamente, piu' in sintesi: 
        ** while ((ch = getchar() != '\n') && (ch != EOF));
        */
    }
    Le funzioni unbuffered, come getch(), non hanno questo genere di problemi e restituiscono direttamente il primo tasto premuto.
    Non accedono ad alcun buffer interno e non richiedono la pressione di tasti specifici. Nulla di particolarmente esotico.
    Quindi se ho capito bene quando questo codice viene eseguito e si arriva sulla getchar il controllo passa al sistema operativo e non ritorna fintanco che non premiamo enter, una volta premuto enter la getchar preleva a uno a uno i caratteri dal buffer e li inserisce nella variabile ch.
    Però quello che non capisco è:
    Tratto da Programmare in c:
    Alcune funzioni dispongono di un buffer dove il sistema operativo memorizza tutti i caratteri finchè l'utente non preme invio per inviarli al flusso stdin. Altre sono prive di buffer, quindi ogni carattere è inviato a stdin non appena viene premuto il tasto corrispondente.

    Che significa inviare al flusso di stdin,cioè dal buffer passano al flusso di stdin e dopo vengono letti dal programma?

  6. #6
    Quote Originariamente inviata da linux_r Visualizza il messaggio
    Però quello che non capisco è:
    Tratto da Programmare in c:
    Alcune funzioni dispongono di un buffer dove il sistema operativo memorizza tutti i caratteri finchè l'utente non preme invio per inviarli al flusso stdin. Altre sono prive di buffer, quindi ogni carattere è inviato a stdin non appena viene premuto il tasto corrispondente.

    Che significa inviare al flusso di stdin,cioè dal buffer passano al flusso di stdin e dopo vengono letti dal programma?
    La scelta fraseologica di codesto testo (probabilmente tradotto) lascia davvero a desiderare. Ciò che avviene, molto grossolanamente, si può descrivere nel modo seguente: il flusso di tasti che costituisce lo stdin viene "travasato" nel buffer di cui sopra, e da lì - alla pressione di ENTER - viene poi reso disponibile a funzioni come getchar().

    In realtà qui dovremmo anche sviscerare il concetto nativo di unix, e quindi del C originale, secondo cui "everything is a file", ma ritengo realmente inutile complicare la trattazione in questo momento.
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    Quote Originariamente inviata da M.A.W. 1968 Visualizza il messaggio
    La scelta fraseologica di codesto testo (probabilmente tradotto) lascia davvero a desiderare. Ciò che avviene, molto grossolanamente, si può descrivere nel modo seguente: il flusso di tasti che costituisce lo stdin viene "travasato" nel buffer di cui sopra, e da lì - alla pressione di ENTER - viene poi reso disponibile a funzioni come getchar().

    In realtà qui dovremmo anche sviscerare il concetto nativo di unix, e quindi del C originale, secondo cui "everything is a file", ma ritengo realmente inutile complicare la trattazione in questo momento.
    in poche paroler il contenuto del buffer non viene spostato nello stdin ma il contrario?

  8. #8
    Quote Originariamente inviata da linux_r Visualizza il messaggio
    in poche paroler il contenuto del buffer non viene spostato nello stdin ma il contrario?
    Il banale concetto sotteso è che le funzioni come getchar() prelevano il loro input dal buffer e lo mettono a disposizione del programma. Tutto qui...
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2014
    Messaggi
    305
    Quote Originariamente inviata da M.A.W. 1968 Visualizza il messaggio
    Il banale concetto sotteso è che le funzioni come getchar() prelevano il loro input dal buffer e lo mettono a disposizione del programma. Tutto qui...
    mmmm ok pero cosi comunque non mi resta chiara la frase del libro . inoltre in una slide fa vedere proprio che dal buffer i dati vengono inseriti nel flusso collegato allo stdin


    Qui le slide di cui ti parlavo
    Ultima modifica di linux_r; 10-05-2014 a 00:05

  10. #10
    Codesto testo (Deitel?) finisce per confonderti solo le idee, specialmente a causa della traduzione piuttosto approssimativa.

    Il buffer al quale si riferiscono le slide che hai referenziato è il buffer di tastiera gestito dal BIOS (nei PC standard trattasi di una coda circolare gestita tramite due puntatori nell'area dati del BIOS) che sta a monte dello standard input, in quella lunga catena della quale si accennava sopra.

    Viceversa, il buffer della getchar() è un buffer interno alla libreria di runtime: come ogni buffer di tale categoria, è qualcosa che si frappone tra il file di input (in questo caso stdin, che è comunque un "file" per il sistema operativo e per il linguaggio C) e il programma stesso. In definitiva, si parla di due distinti buffer, con meccanismi di gestione diversi, a carico di entità ben distinte.

    Ribadisco, per maggior chiarezza: quando si parla di buffered input per le funzioni di libreria come getchar(), ci si riferisce al buffer interno alla libreria e in particolare alla necessità di terminare ciascun input con ENTER.
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

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 © 2024 vBulletin Solutions, Inc. All rights reserved.