Newsgroup: it.comp.lang.c
Titolo: Funzioni che leggono una linea dallo stream  tipo fgets() ecc.

Sto studiando C da qualche settimana e volevo alcuni chiarimenti...
 
In C ci sono molte funzioni per leggere i dati ingressati da tastiera.
Ad esempio gets(), fgets(), sscanf() ecc. ecc.
Ognuna di queste funzioni si contraddistingue da come legge il dato 
ingressato, precisamente appartiene a una di queste tre modalità:
 
stdin  	stream  stringa
 
Qualcuno mi potrebbe spiegare cosa si intente per
stdin  	stream  stringa ?
 
Grazie tanto
nero23


In C quando si parla di "stream" s'intende i FILE* (quelli che ottieni con
fopen, per dirne una).
Ogni programma C ha, alla partenza, tre stream già aperti e pronti all'uso,
che sono stdin, stdout e stderr, che sono standard input, output e error
rispettivamente (che solitamente leggono e scrivono dallo stesso terminale o
finestra).
Quindi, scrivere c=getchar() oppure c=getc(stdin) è perfettamente identico,
così come è uguale scrivere printf("ciao") e fprintf(stdout, "ciao").
 
Per quando riguarda le stringhe nella tua domanda, la libreria standard non
ti permette di vedere una stringa come uno stream, e quindi hai bisogno di
funzioni equivalenti a quelle su file ma che operano su stringhe. Unita a
fscanf() avrai sscanf(), fprintf() e sprintf(), etc. (1)
 
Spero di aver risposto a qualcuno dei tuoi dubbi!
 
Ciao!
 
(1) Nota che non esiste una, mettiamo sgets(), perché al contrario di uno
stream, la stringa è un array che puoi scorrere e tagliare a tuo piacimento!

Scusami se insisto, ma sono temo di essere ancora confuso :(
 
Quando leggo che  l'input di una funzione avviene da stream,
piuttosto che da stdin  oppure da stringa, cosa si intende esattamente?
 
 
 
 
Ciao
 
nero23


Come prima cosa stdin *è* uno stream, quindi rimangono solo stream e stringa.
Uno stream è un file, una stringa è una stringa.
fscanf(file, "%d", &i); /* legge un intero dallo stream "file" */
sscanf(str, "%d", &i); /* legge un intero dalla stringa "str" */
scanf("%d", &i); /* uguale a fscanf(stdin, "%d", &i); */
 
Un po' più chiaro?
Ciao!


Massei ti ha già esaurientemente risposto su questo
Aggiungo solo gets non usarla in quanto insicura
Nello  std C11 è stata eliminata
 


 
 
Che cosa si utilizza come sostituto di gets?
 
Ciao 
 
 

 
 
fgets(), ma da sempre! :-)
Ti fa il controllo sulla dimensione del buffer, in maniera che non è possibile
sforare. Penso abbiano eliminato gets in quanto veramente non la usava nessuno.
Ciao!


 
fgets(), ma da sempre! :-)
Ti fa il controllo sulla dimensione del buffer, in maniera che non è 
possibile
sforare. Penso abbiano eliminato gets in quanto veramente non la usava 
nessuno.
Ciao!
 
 
fgets si utilizza per l'input da console?
 
 
Ciao 
 
 

 
 
eh sì :)
mai visto un programma con un main del tipo:
 
int main(void)
{
    char buf[100];
    while (fgets(buf, sizeof(buf), stdin)!=NULL) {
        /* ... */
    }
    return 0;
}
 
?
io minimo minimo un centinaio! :-)
 
Ciao!


 
Anche la console (ptty) dal punto di vista del kernel è un file a linee 
(ioctl  a parte) quindi i buffer overflow possono capitare anche li
a meno di non sapere quanto è la max linea di lettura
Però a questo punto devi sapere se il descrittore 0 è associato alla 
console o ad un file
 
 

 console o ad un file
 
Su questo non ti seguo, o meglio non ho capito cosa intendi..
Il possibile overflow con gets() ce l'hai al livello di applicazione, non di
kernel, sul buffer dove vai a copiare i dati dello stream che leggi. Il fatto
che sia un kernel *unix o no, che nel primo caso stdin sia o meno sul
descrittore zero, che sia una tty o un file, non influisce sul problema.
 
Ciao!


Forse mi sono spiegato male.
L' overflow con il kernel, come ben sai anche tu,non c'entra niente
Volevo solo dire che il kernel unix fa vedere i terminali come se 
fossero flussi, sostanzialmente un comune flusso a linee (ioctl a parte).
Quando da programma utente leggo da stdin (il descrittore 0) normalmente 
non mi preoccupo di sapere se il descrittore è agganciato al terminale o 
ad un comune file.
Ecco quindi che il problema di gets viene fuori lo stesso anche se leggo 
da stdin
Comunque, visto che gets è mancante dalla libreria standard da C11 tanto 
vale dimenticarsene se non  come ricordo storico o come monito per i 
buffer overflow, tanto prima o poi capiterà a tutti di usare un 
compilatore C11 o successivo
 

 compilatore C11 o successivo
 
Speriamo tutti presto! ;)
 
Ciao!


 
Salute