Newsgroup: it.comp.lang.c
Titolo: Aiuto! Cosa c'è che non va?(alle prime armi)

Salve, premetto che sono alle prime armi dello studio del C.
Ho scritto un piccolo listato per provare e verificare l'utilizzo di una
struttura, ma il programma si comporta in modo strano, ovvero non rispetta
gli 'input'. (Fa un po quello che gli pare, sembra quasi che ogni input che
gli do lo memorizzi e ripeta automaticamente l'ultimo carattere nell'input
successivo, almeno credo...). Aiutatemi, vi prego! cosa c'è che non va in
questo programma???
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct tab {
    char nome[30];
    char indirizzo[30];
    int cap;
    char citta[15];
} scheda;
void enter(void);
void show(void);
void main(void)
{
    char ch;
    for (;;) {
        clrscr();
        printf("Digita la scelta:\n");
        printf("\na) Inserisci gli elementi");
        printf("\nb) Visualizza gli elementi");
        printf("\nc) Esci\n\n");
        printf("Eseguire: ");
        ch=getchar();
        switch (ch) {
            case 'a':
                enter();
                break;
            case 'b':
                show();
                break;
            case 'c':
                exit(0);
        }
    }
}
void enter(void)
{
    printf("\n\nInserisci il nome: ");
    gets(scheda.nome);
    printf("\nInserisci l'indirizzo: ");
    gets(scheda.indirizzo);
    printf("\nInserisci il CAP: ");
    scanf("%d", &scheda.cap);
    printf("\nInserisci la città: ");
    gets(scheda.citta);
}
void show(void)
{
    printf("\n\nNome: %s", scheda.nome);
    printf("\nIndirizzo: %s", scheda.indirizzo);
    printf("\nCAP: %d", scheda.cap);
    printf("\nCittà: %s", scheda.citta);
    getchar();
}

questo programma???
Il problema sarà sicuramente dovuto all'utilizzo di "getchar" che bufferizza
l'input fino alla pressione del tasto "Invio". In parole povere, se digiti
più caratteri alla chiamata della funzione "getchar" questi vengono tutti
memorizzati e poi "rilasciati uno per uno".
Prova ad eseguire quanto segue.
#include <stdio.h>
int main()
{
    char ch=0;
    puts("Inserisci caratteri");
    while(ch != 'q') {
        printf("Carattere: %c\n",ch = getchar());
    }
    puts("\nSecondo ciclo");
    while(ch != 't') {
        printf("Carattere: %c\n",ch = getchar());
    }
    return 0;
}
Inserisci una serie di caratteri in cui sia presente prima una "q" e poi una
"t" (ad esempio "pippoqpippot") e premi Invio.
L'output è il seguente:
Carattere: p
Carattere: i
Carattere: p
Carattere: p
Carattere: o
Carattere: q
Secondo ciclo
Carattere: p
Carattere: i
Carattere: p
Carattere: p
Carattere: o
Carattere: t
--
Francesco Trotta
http://space.tin.it/computer/ftrotta
Elimina "x_" dal mio indirizzo per mandarmi
un messaggio direttamente

...

Ho capito! L'errore sta nel fatto che getchar() è bufferizzato, di
conseguenza l'input rimane memorizzato (compreso l'invio "\n") e viene
utilizzato per le immissioni successive. Proprio come dicevi tu.
Anche se l'output del tuo programma di test ha una inesattezza, infatti si
presenta così:
Carattere: p
Carattere: i
Carattere: p
Carattere: p
Carattere: o
Carattere: q
Secondo ciclo
Carattere:                    <-- La riga che ti sei "dimenticato" di
scrivere....
Carattere: p
Carattere: i
Carattere: p
Carattere: p
Carattere: o
Carattere: t
Infatti, il comando di "invio" dopo la 'q' del primo ciclo è considerato nel
buffer, e viene poi immesso come primo input del secondo ciclo.
Grazie, sei stato davvero gentile, ti ringrazio tanto perchè ora ho capito.
Però, purtroppo, rimane un problema: se getchar() non fa al caso del mio
programmino, per i motivi visti sopra, cosa posso usare al suo posto? Quale
funzione di libreria esegue lo stesso compito senza bafferizzare?
Spero che tu possa rispondermi.....
Grazie ancora per la tua disponibilità.
Ciao

Quale funzione di libreria esegue lo stesso compito senza bafferizzare?
Puoi continuare pure ad usare "getchar()".
Puoi scrivere ad esempio :
int c, d ;
c = getchar() ; /* legge il carattere */
d = c ;
while ( d != '\n' ) d = getchar() ; /* svuota il buffer */
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org

funzione di libreria esegue lo stesso compito senza bafferizzare?
Solitamente ogni compilatore ne fornisce di alternative: ad esempio io
utilizzo il Borland Turbo C++ 1.0 che ha getch() e getche().
Per rimanere nello standard puoi o utilizzare fgetc(stdin) o svuotare il
canale ad ogni operazione di lettura con "fflush(stdin)": soluzioni da
evitare se cerchi l'efficienza del programma.


 canale ad ogni operazione di lettura con "fflush(stdin)"
Tanto per mettere le cose in chiaro, fflush(stdin) secondo lo standard
causa un comportamento implementation defined; fflush e' definito SOLO
per gli output streams (ISO 7.9.5.2).
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

     gets(scheda.nome);
Invece delle gets() sarebbe meglio utilizzare fgets() che ti permette di
specificare la lunghezza massima del buffer che deve contenere la
stringa:
fgets(scheda.nome, 30, stdin);
EMG

evitare se cerchi l'efficienza del programma.
Ehm.... io so che "fflush()" funziona solo per gli stream di output ...


Grazie mille a tutti, mi siete stati di grande aiuto.
Grazie Francesco, Andrea, Maurizio e EMG.
Spero di poter porre altre domande qualora mi sorgessero altri dubbi durante
l'inesauribile cammino dell'apprendimento di questo meraviglioso linguaggio
(ammazza che frase!)!
A parte gli scherzi grazie e un saluto a tutti.
Ciao

 canale ad ogni operazione di lettura con "fflush(stdin)"
In C, fflush(stdin) ha un comportamento 'undefined'.
EMG

Chiedo pubblicamente perdono. :-)
Ho guardato la definizione sulla guida del Borland Turbo C++ 1.0 che non
lascia intendere l'utilizzo limitato solo ai canali di output. Consultando
invece il manuale che utilizzo ("La guida completa del C" - Schildt -
pag.211)
"Per vuotare il contenuto di un canale di output si utilizza la funzione
fflush() ... Questa funzione scrive il contenuto di un buffer nel file
associato. Se si richiama fflush() con un puntatore a file nullo, verranno
svuotati i buffer di tutti i file."
Saluti
