• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Guida [C] Come salvare correttamente i dati da stdin.

ParadiseCity

Utente Assiduo
Autore del topic
17 Aprile 2010
588
0
Miglior risposta
0
Chiariamo prima di tutto cos'è la stdin. La stdin non sarebbe altro che l'input dal quale digitiamo tutti i comandi. Quando pigiamo sulla tastiera un tasto, non facciamo altro che inviare in input al nostro computer un codice binario che identifica quel tasto e che ci permette di interagire con la macchina, per questo motivo è molto importante in C come in tutti i linguaggi avere ben chiaro come sfruttare lo stdin per salvare dei dati che vogliamo immettere. Si pensi ad esempio ad una calcolatrice, come potremmo interagire per eseguire le operazioni se non utilizzassimo l'input!?


In C abbiamo vari modi per salvare i dati dentro le variabili, essi sono principalmente 4:

-scanf
-fgets
-gets
-libreariadline (utilizzato solo su Linux)


La sintassi di scanf è la seguente:

scanf("%d", &a);

La d vicino il %, richiama il tipo di dato in questo caso int (numero intero) la a sarebbe la variabile nella quale salvare il dato. Ma passiamo ad esaminare un pezzo di codice:

PHP:
Perfavore, Entra oppure Registrati per vedere i codici!

Vi è il rischio overflow in questo pezzo di codice difatti scanf, non controlla la lunghezza della stringa inserita, quindi il programma è a rischio crash, tuttavia vi sono dei casi in cui è preferibile l'uso della scanf, come in combinazione con le struct, con le quali è più difficile usare fgets che andremo a vedere ora.





Fgets è un'istruzione molto sicura e alquanto funzionale in un programma, per salvare dati in una variabile. La sua sintassi è la seguente:

fgets( a, 10, stdin);

Dove a sarebbe la variabile nel quale salvare i dati, 10 la lunghezza massima consentita e la stdin corrisponde al nostro input, ovvero comunichiamo a fgets che provengono dei dati da stdin. Inoltre la fgets prende in input sempre n-1 caratteri per cui, nel codice saranno 9 caratteri al massimo.

PHP:
Perfavore, Entra oppure Registrati per vedere i codici!

Come potete intuire fgets controlla la lunghezza della stringa inserita, quindi è più sicura per il programma evitando crash eliminando il possibile overflow. Come detto in precedenza, a volte bisogna preferire scanf, ma fgets resta sicuramente una valida funzione per salvare dei dati da Stdin.





Gets invece si considera totalmente obsoleta e si studia solo per dovere di cronaca. Essa si trova nella libreria(libreria è solo il significante italiano, il termine corretto è header) stdio.h ed viene sconsigliato fortemente, in quanto fa andare quasi sempre il programma in overflow. Per capire meglio esaminiamo un pezzo di codice:

PHP:
Perfavore, Entra oppure Registrati per vedere i codici!


Come possiamo notare viene salvato il dato inserito nella variabile senza alcun controllo! Ciò mette a serio rischio il programma, difatti al 99% ci sarà un crash utilizzando questa funzione, che è mantenuta nelle librerie del C solo per retrocompatibilità. Il controllo infatti non avviene ne sul tipo della variabile ne sulla grandezza, per cui il mio consiglio è di limitarsi alla conoscenza di questa funzione.




Infine la libreriadline, prerogativa esclusivamente dei sistemi linux che è caldamente consigliato per imparare a programmare, specialmente in C. Si consideri che ci sono molte funzioni che sono disponibili solo su Linux per quanto riguarda il C; per poterla utilizzare basta includere nel vostro programma queste due header:

#include <readline.h>
#include <history.h>


Per salvare i dati basta usare questo codice:

PHP:
Perfavore, Entra oppure Registrati per vedere i codici!

Che non fa altro che leggere da input attraverso readline, la linea corrente di tipo char(carattere). Passiamo ad analizzare il codice; char indica il tipo di variabile, in questo caso carattere, *line è un puntatore. Readline invece è un istruzione che permette di leggere quello che verrà scritto fra ".." e salvarlo nella variabile. Ricordo nuovamente che questo metodo è utilizzabile solo su Linux.




La guida la ho scritta personalmente, senza copiarla da nessun forum e\o altra sorgente. Spero che vi sia utile^^
 
Ultima modifica:
Riferimento: [C] Come salvare correttamente i dati da stdin.

Spero che vi sia utile^^

Spero che siano utili anche alcune correzioni ...


In C abbiamo vari modi per salvare i dati dentro le variabili, essi sono principalmente 4:

-scanf
-fgets
-gets
-libreariadline

Il metodo più semplice per "salvare i dati dentro delle variabili" in C è assegnarne il valore nel codice, come

a = b + c;

Quello di cui parli è come fare a "leggere dati da periferiche" (tastiera, disco) e memorizzarli in variabili.
I metodi ovviamente, non sono solo quelli ...

La "libreariadline" non è caratteristica del C ma dei sistemi Linux ... non può essere intesa come "metodo standard" !

char a[10];

printf("Inserisci una stringa ");
scanf("%d", &a);

Questo esempio di codice è sbagliato in quanto prevede l'input di un dato numerico

%d

in un array di char ... in realtà dovrebbe essere

scanf("%s", a);

senza & in quanto il nome di un array di char equivale al suo indirizzo e quindi non si aggiunge il &

Per la fgets bisogna ricordare che i dati inseriti devono considerare il fatto che la stringa in C è terminata dal nul (0 binario) e quindi i caratteri inseriti saranno al massimo uno in meno (9 nell'esempio). Nel caso in cui non siano il massimo, bisogna fare attenzione perché viene aggiunto anche il carattere di LF (0A in esadecimale) alla fine della stringa.

libreria stdio.h

stdio.h e simili NON sono librerie.

Vedo continuamente queste stupidaggini nelle guide. Fate attenzione ... quelli sono solo file include che contengono le "firme" delle funzioni. Le librerie sono altri file (.lib, .a, .dll) che contengono l'implementazione delle funzioni.
 
Riferimento: [C] Come salvare correttamente i dati da stdin.

Spero che siano utili anche alcune correzioni ...

Non c'è bisogno di essere ironici ;)


Il metodo più semplice per "salvare i dati dentro delle variabili" in C è assegnarne il valore nel codice, come

a = b + c;

Quello di cui parli è come fare a "leggere dati da periferiche" (tastiera, disco) e memorizzarli in variabili.
I metodi ovviamente, non sono solo quelli ...

La "libreariadline" non è caratteristica del C ma dei sistemi Linux ... non può essere intesa come "metodo standard" !

La libreariadline invece deve essere considerato un metodo standart in quanto il sistema operativo dei programmatori è linux, è risaputa la debolezza di Windows e la scomodità di Mac; per cui è anche un invito ad usare Linux.


Questo esempio di codice è sbagliato in quanto prevede l'input di un dato numerico

%d

in un array di char ... in realtà dovrebbe essere

scanf("%s", a);

senza & in quanto il nome di un array di char equivale al suo indirizzo e quindi non si aggiunge il &

Per la fgets bisogna ricordare che i dati inseriti devono considerare il fatto che la stringa in C è terminata dal nul (0 binario) e quindi i caratteri inseriti saranno al massimo uno in meno (9 nell'esempio). Nel caso in cui non siano il massimo, bisogna fare attenzione perché viene aggiunto anche il carattere di LF (0A in esadecimale) alla fine della stringa.

Non me ne ero accorto, dato l'orario, provvedo.


nothing ha detto:
stdio.h e simili NON sono librerie.

Vedo continuamente queste stupidaggini nelle guide. Fate attenzione ... quelli sono solo file include che contengono le "firme" delle funzioni. Le librerie sono altri file (.lib, .a, .dll) che contengono l'implementazione delle funzioni.


La stdio.h è un header, ma in italiano è intesa come una libreria, è il significante della stdio.h. Specificherò meglio nel thread.
 
Ultima modifica:
Riferimento: [C] Come salvare correttamente i dati da stdin.

Non c'è bisogno di essere ironici ;)

Ma che ironici. Lo penso davvero.

Evita commenti inutili (lo dico ai moderatori ...)

La libreariadline invece deve essere considerato un metodo standart in quanto il sistema operativo dei programmatori è linux, è risaputa la debolezza di Windows e la scomodità di Mac; per cui è anche un invito ad usare Linux.

Non diciamo stupidaggini per cortesia.

La stdio.h è un header, ma in italiano è intesa come una libreria, è il significante della stdio.h. Specificherò meglio nel thread.

I programmatori italiani che conosco io non intendono affatto un file header come libreria. Non c'è significante (che vuoi dire?) che tiene.

Un file header ha un suo specifico scopo (e al massimo lo chiami file di intestazione in italiano)

Una libreria è un'altra cosa.

Se si fanno delle guide, non ci si deve inventare nulla ...

Un'ultima cosa ... accetta consigli da chi programmava in C da quando tu non eri neanche nato ...
 
Riferimento: [C] Come salvare correttamente i dati da stdin.

nothing ha detto:
Un'ultima cosa ... accetta consigli da chi programmava in C da quando tu non eri neanche nato ...

Di certo non accetto critiche da chi si pone su un piedistallo non rispondendo a messaggi privati, nei quali si chiede una mano e viene a fare il primo della classe successivamente. Siamo in un forum, cerchiamo di aiutarci, qualcosa era sbagliata nella guida, ho accettato lo sbaglio ed ho corretto e tu continui ad essere altezzoso, ora basta.

nothing ha detto:
I programmatori italiani che conosco io non intendono affatto un file header come libreria. Non c'è significante (che vuoi dire?) che tiene.

Libreria è il significante se non sai cosa significa, basta pigliare un vocabolario della lingua italiana e lo cerchi.

nothing ha detto:
Non diciamo stupidaggini per cortesia.

Linux è il sistema operativo dei programmatori in quanto è meno vulnerabile e consente di visualizzare i codici. Non sei d'accordo!? ok ma i fatti mostrano altro.


Se hai qualcosa da ridire me la invii per pm.
 
Riferimento: [C] Come salvare correttamente i dati da stdin.

Ho fatto solo dei rilievi "tecnici" alla tua guida.

Per il resto, pensala come vuoi, non ho tempo da perdere.
 
Ultima modifica:
Riferimento: [C] Come salvare correttamente i dati da stdin.

Ragazzi basta commentare inutilmente e creare flame.
Cercate di mantenere la calma, e di discutere privatamente di altre questioni.
 
Riferimento: [C] Come salvare correttamente i dati da stdin.

Ragazzi basta commentare inutilmente e creare flame.
Cercate di mantenere la calma, e di discutere privatamente di altre questioni.


Sono assolutamente d'accordo con te, la guida è nata per aiutare i ragazzi alle prime armi, dato che lo stdin è la cosa più importante da capire per iniziare a programmare decentemente in C.
 
Riferimento: [C] Come salvare correttamente i dati da stdin.

Ragazzi basta commentare inutilmente e creare flame.
Cercate di mantenere la calma, e di discutere privatamente di altre questioni.

D'accordissimo ... manteniamo la calma e commentiamo solamente dal punto di vista tecnico i post, dato che è importante che chi è alle prime armi riceva informazioni corrette ... sarai d'accordo anche tu ...