Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [c] errore di gestione dello stdin

    ciao a tutti

    ho creato un programma che crea una lista di tipo LIFO , e che scrive la stessa in un file binario

    ora questo programma è strutturato in questo modo :

    codice:
    
    typedef struct meteo
    {
    	char nome [12] ;
    	int numero ;
    	struct meteo *next ;
    }meteo ;
    
    typedef meteo *meteoPtr ;
    in pratica la lista prevede che ogni nodo abbia una stringa (nome) e un numero identificativo


    ora agendo in questa maniera

    codice:
    do {
    	 
    		fprintf(stdout , "digita 0 per finire  \n" ) ;
    		fscanf (stdin , "%d" , &i ) ;
    		Testa = crea (Testa ) ;
    		n++ ;   /* contatore numero nodi */
    
    	} while ( i != 0 ) ;

    e richiamando la funzione "crea"

    codice:
    
    meteoPtr crea (meteoPtr *l ) 
    
    {
    	meteoPtr nuovo ; /* creo un nuovo nodo */
    	nuovo = (meteoPtr*) malloc (sizeof (meteo) ) ;
    	nuovo->numero = 1 + rand () % 100 ;
    	fgets (nuovo->nome , 10 , stdin ) ;
    	
    
    	nuovo->next = l ;
    
    	return nuovo ;
    
    }

    il programma qualora digito 0 subito , mi genera un numeo casuale , ma ignora
    la funzione fgets (per la creazione di stringa)


    e in ogni caso , genera sempre un valore ( numero casuale) , superiore al numero
    di stringhe presenti , come se "l'ultima volta" ignorasse fgets

    qualcuno mi sa spiegare perchè?

    grazie

  2. #2
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Devi pulire il buffer,ora se sei su windows anche se dicono che fa schifo perchè non è portabile,puoi usare questa funzione da mettere dentro al ciclo:
    codice:
    fflush(stdin);
    E ti pulisce il buffer.
    Se non sei su windows puoi usare questo:
    codice:
    while(getchar()!=10)
        ;
    Il punto e virgola sta a significare un' istruzione vuota,cioè che il flusso di istruzioni si ferma finchè non si incontra il carattere newline nel buffer,ma è più difficile da gestire di fflush.

  3. #3
    problema risolto , ma pensa te!

    grazie

    codice:
    do {
    	 
    		
    		fprintf(stdout , "digita 0 per finire  \n" ) ;
    		
    		fscanf (stdin , "%d" , &i ) ;
    		fflush(stdin);
    		
    		
    
    		Testa = crea (Testa ) ;
    		
    		n++ ;
    
    	} while ( i != 0 ) ;
    ho inserito la fflush per svuotare il buffer

    adesso crea in ogni caso almeno un nodo , e poi qualora lo volessi , anche altri
    che sistema operativo usi?

    grazie

  4. #4
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    A bene,ancora una volta la mia saggezza ha avuto la meglio

    Uso linux,ma su windows fflush è comodissima infatti prima usavo windows e era facilissimo svuotare il buffer.
    Su linux anche,ma non con fflush.

  5. #5
    Originariamente inviato da ramy89
    A bene,ancora una volta la mia saggezza ha avuto la meglio

    Uso linux,ma su windows fflush è comodissima infatti prima usavo windows e era facilissimo svuotare il buffer.
    Su linux anche,ma non con fflush.
    Colgo al volo l'occasione: cosa usi su linux? sai se è portabile su Mac?
    Salute a voi, da Laikius!

    --> Faber est suae quisque fortunae <--

  6. #6
    Originariamente inviato da ramy89
    A bene,ancora una volta la mia saggezza ha avuto la meglio
    Ti devo correggere:
    codice:
    while(getchar()!='\n')
        ;
    Dato che lo standard non garantisce che 10=='\n'.

    Nota che se cerchi di svuotare un buffer di input già vuoto con questo metodo il programma si mette ad attendere input da tastiera dall'utente. D'altra parte fflush(stdin) non è solo non portabile, ma è undefined behavior, il che significa che in teoria può accadere qualunque cosa (nasal demons inclusi).
    If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
    (C99, §7.19.5.2, ¶2)
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Se ho un altro "volevo vedere se eri attento" me lo uso adesso


    Uso code::blocks che alla fine è uguale a quello fatto per windows,con GCC.
    Delle volte da problemi ma alla fine sono soddisfatto,poi in generale non penso siano portabili,per renderla portabile c'è quasi sempre qualcosa da fare.Poi conta che su mac anche se non è LINUX (il che equivale a dire UNIX gratuito ma anche trasandato) lo stdin non è uguale allo stdin su altre macchine.
    Per cui se l' interfaccia standard non è la stessa può essere che il codice funzioni perfettamente,ma questo non è garantito (se ho sbagliato qua mi uso pure il terzo ).

  8. #8
    Originariamente inviato da ramy89
    Se ho un altro "volevo vedere se eri attento" me lo uso adesso

    Delle volte da problemi ma alla fine sono soddisfatto,poi in generale non penso siano portabili,per renderla portabile c'è quasi sempre qualcosa da fare.
    Il punto è questo: se usi solo C e C++ standard, evitando tutti i casi di undefined e unspecified behavior il tuo codice dovrebbe funzionare in maniera perfettamente identica su qualunque sistema operativo tu lo esegua. Se hai necessità che esulano dallo standard (una su tutte: GUI) o usi codice platform-specific (API Win32 su Windows, syscall POSIX e X su *NIX, ...) oppure librerie che astraggono queste differenze (ad esempio le wxWidgets, su cui si basa lo stesso Code::Blocks).
    Poi conta che su mac anche se non è LINUX (il che equivale a dire UNIX gratuito ma anche trasandato) lo stdin non è uguale allo stdin su altre macchine.
    Per cui se l' interfaccia standard non è la stessa può essere che il codice funzioni perfettamente,ma questo non è garantito (se ho sbagliato qua mi uso pure il terzo ).
    L'stdin/stdout e tutte le altre facilities standard sono uguali su tutte le macchine finché rientri nei casi d'uso previsti dallo standard; ciò che succede quando esci da queste specifiche dipende dall'implementazione.
    Amaro C++, il gusto pieno dell'undefined behavior.

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.