Newsgroup: it.comp.lang.c
Titolo: gets puts

salve !
#include <stdio.h>
main() {
char s[80]; /* dichiara la stringa */
gets(s); /* riceve l'input */
puts(s); /* fornisce l'output */
}
forse commetto un errore ma quando lo lancio ottengo dei mex di
errore....dovrei fornire dei parametri?....
io lancio ./a.out (il prog compilato su linux) ottengo una sfilza di mex che
mi avvertono che addirittura "is dangerous"!!!
miiii e che e'??????
ciao e grazie

 mi avvertono che addirittura "is dangerous"!!!
il prog compila..il messaggio d'errore dovrebbe essere a riguardo della gets()
che gcc segna in quanto non controlla la lunghezza dell'input.
Tu hai "char s[80]" quindi se son la gets() prendi 81...vai in overflow..
Usa fgets().
Regards,
-- 
      SNHYPER
"Security developer"
http://snhyper.owns.it
Linux registered { user #249109, machine #133922 };

mi avvertono che addirittura "is dangerous"!!!
Gli errori non dovrebbero esserci in fase di esecuzione, ma in fase di
compilazione, ma non si tratta di errori, bensì di warning, infatti
l'eseguibile viene generato lo stesso.
Il problema sta nella funzione gets, che pur essendo molto comoda,
contiene un bug, infatti non limita il numero di caratteri da leggere
quindi può portare ad un buffer overflow, ovvero se tu nell'input dai
una stringa lunga più dello spazio che hai allocato dichiarando il
vettore di char, il programma terminerà con segmentation fault perchè
la gets tenterà di accedere ad uno spazio in memoria che non è stato
allocato per il tuo programma.
Cmq il tuo programma è perfettamente funzionante per input minori di
79 caratteri (l'ultimo viene riempito con '\0' il terminatore di
stringa), ma se vuoi rimediare al warning della gets usa fgets:
char *fgets(char *s, int size, FILE *stream);
quindi la tua gets diventerebbe 
fgets(s,79,stdin);
così non ti darà nessun errore, l'unico problema è che con gets il \n
non viene salvato nella stringa, mentre in fgets si, a te il compito
di eliminarlo, altrimenti quando la stampi con puts l'output sarà:
$./a.out
stringa\n   /*input*/
stringa\n   /*output*/
\n            /*output*/
$               /*prompt*/
fabi...@inwind.it
Studente di Informatica presso La Sapienza

 allocato per il tuo programma.
Buffer overflow e segmentation fault non sono fratelli. Si puo' avere uno
sforamento dell'array (buffer overflow) senza che ci sia un segmentation
fault. 
int main(void)
{
   char getsBuff[2];
   char otherBuff[2000];
   gets(getsBuff);
   printf("%s\n", getsBuff);
   return 0;
}
sotto Windows funziona una meraviglia anche dando in input stringhe
parecchio piu' lunghe di 2 caratteri. E' possibile che la stessa cosa
capiti con Linux.
C:\>iao Angelo
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 fgets(s,79,stdin);
       fgets()  reads  in  at  most one less than size characters
       from stream and stores them into the buffer pointed to  by
       s.  Reading stops after an EOF or a newline.  If a newline
       is read, it is stored into the buffer.  A '\0'  is  stored
       after the last character in the buffer.
quindi:
fgets(s, 80, stdin);
In caso di array e` piu` comodo usare:
fgets(s, sizeof(s), stdin);
cosi`  la  variazione  della  lunghezza  dell'array  richiede  una  sola
modifica al codice.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Fare l'amore con dieci donne e` fantastico, soprattutto perche` ti
 presentano un sacco di amiche." -- Fabio Di Iorio

C:\>iao Angelo
Ciao
############################################
Fabio
fabi...@inwind.it
Studente di Informatica presso 
l'Università degli Studi La Sapienza
############################################

Kronos
Ciao
############################################
Fabio
fabi...@inwind.it
Studente di Informatica presso 


 Non e` detto che funzioni sempre.
Appunto, e` undefined behaviour. Come ho  gia` detto altre volte la cosa
dipende  strettamente  dal  compilatore,  OS,  hardware. Il  crash  puo`
avvenire solo se il kernel si  accorge dello sforamento e questo avviene
solo quando  si verifica un page  fault. Per lo stack del  mio programma
viene allocata almeno una pagina, quindi potrei andare avanti a scrivere
per un  bel po'  prima di  sforare da  questa pagina  e causare  un page
fault. Guarda questo:
Script started on Mon Oct 21 21:17:59 2002
kronos:~/c$ cat p1.c
#include <stdio.h>
int main(void) {
	int i;
	char b[80];
	for (i = 0; i < 10000; i++)
		b[i] = 'a';
}
kronos:~/c$ gcc -Wall -std=c99 -g -op p1.c
kronos:~/c$ gdb p
(gdb) run
Starting program: /home/kronos/c/p 
Program received signal SIGSEGV, Segmentation fault.
0x08048458 in main () at p1.c:8
8			b[i] = 'a';
(gdb) print i
$1 = 1904
(gdb) quit
The program is running.  Exit anyway? (y or n) y
kronos:~/c$ exit
Script done on Mon Oct 21 21:18:25 2002
Ha ragione Angelo: overflow != crash
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Al termine di un pranzo di nozze mi hanno dato un
amaro alle erbe cosi' schifoso che perfino sull'etichetta
c'era un frate che vomitava.

 risultato ottieni.
Che funziona. Anche andando oltre (e di parecchio) l'ottantesimo carattere
(sara' un caso particolare, ma non e' raro. Kronos ti ha spiegato i motivi
di questo comportamento).
Non fidarti mai del fatto che sforando un array ottieni un crash. Il crash
in un programma non e' il peggio che ti puo' capitare (anzi, per programmi
che si comportano male, un crash immediato e' una botta di culo 
incredibile).
Il peggio e' quando sfori l'array, sovrascrivi dati che usi piu' tardi e
questi ti rendono il file (per il quale hai impiegato tre giorni di
elaborazione) inutilizzabile :-).
Happy programming!


 O sbaglio?
Autoquotandomi:
       fgets()  reads  in  at  most one less than size characters
       from stream [...]
Quindi con size == 80 fgets legge  *al massimo* 79 caratteri, in modo da
poter inserire il terminatore nell'ottantesimo posto. Nel caso limite ti
troverai  con  un  array  le  cui posizioni  [0-78]  sono  occupate  dai
caratteri letti, mentre nella posizione [79] c'e` il terminatore '\0'.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
#include <stdio.h> 
int main(void) {printf("\t\t\b\b\b\b\b\b");
printf("\t\t\b\b\b\b\b\b");return 0;}

caratteri letti, mentre nella posizione [79] c'e` il terminatore '\0'.
Hai ragione, ho sbagliato la traduzione, capita.
