GCC - errore nella compilazione quando utilizzo gets

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
fred_151
Prode Principiante
Messaggi: 4
Iscrizione: mercoledì 8 dicembre 2010, 18:12

GCC - errore nella compilazione quando utilizzo gets

Messaggio da fred_151 »

Buongiorno a tutti,
                        ho scritto un piccolo programma in c che utlizza la gets per acquisire una stringa. La compilazione va buon fine, ma quando eseguo il programma, l'istruzione gets viene saltata, non richiede l'input all'utente. Se utilizzo un scanf tutto funziona. Perchè se compilo con l'istruziona gets, l'eseguibile salta l'istruzione?

Perchè gcc non compila correttamente?
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da bite »

Che cosa ti fa pensare che gcc non compili correttamente?

Se tu postassi il tuo codice, probabilmente troveremmo che il problema risiede lì.
fred_151
Prode Principiante
Messaggi: 4
Iscrizione: mercoledì 8 dicembre 2010, 18:12

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da fred_151 »

Ovviamente questo non è il programma originale, ma si verifica lo stesso problema. Sicuramente non è un problema di gcc (spero).

Codice: Seleziona tutto

#include <stdio.h>
#define N 30

int main(int argc, char * argv[]){
	char nome[N+1];
	int n;
	
	scanf("%d", &n);
	gets(nome);
	printf("%s", nome);
	 
	return 0;
}
Ultima modifica di fred_151 il mercoledì 8 dicembre 2010, 19:38, modificato 1 volta in totale.
Avatar utente
Mefrio
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1426
Iscrizione: martedì 12 gennaio 2010, 20:30
Desktop: Pantheon
Distribuzione: elementary OS

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da Mefrio »

ma nome[] da che è composto?
Want some projects to join in? Help me and community: Scratch, AppCenter, Snap, and many others...
Wiki?
Ikitt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1816
Iscrizione: mercoledì 24 ottobre 2007, 12:05

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da Ikitt »

Codice: Seleziona tutto

$ cat a.c
#include <stdio.h>
#define N 30

int main(int arg, char * argv[]){
	char nome[N+1];
	int n;
	
	scanf("%d", &n);
	gets(nome);

	printf("%i: %s\n", n, nome);
	 
	return 0;
}
$ gcc a.c
/tmp/ccXHgz4p.o: In function `main':
a.c:(.text+0x30): warning: the `gets' function is dangerous and should not be used.
$ echo "12pippo" | ./a.out 
12: pippo
fred_151
Prode Principiante
Messaggi: 4
Iscrizione: mercoledì 8 dicembre 2010, 18:12

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da fred_151 »

Per Mefrio... credo che il codice sia così semplice che non necessiti di alcuna spiegazione aggiuntiva. Pregherei di scrivere commenti che riguardino solo il problema.
Grazie Ikitt,ma vorrei una spiegazione del perchè se lo eseguo normalmente non funziona. Non voglio ricorrere a "trucchi".
Ultima modifica di fred_151 il mercoledì 8 dicembre 2010, 19:26, modificato 1 volta in totale.
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da bite »

Come si rileva dal test (forse un po' criptico ;D) di Ikitt, il problema sta nell'uso in successione di scanf e gets.

scanf legge fino a un whitespace character, che in questo caso è il newline, e non lo toglie di mezzo ma lo lascia nel buffer di ingresso.

scanf, per essere compatibile con se stessa, scarta i whitespace iniziali. Quindi se la seconda lettura venisse fatta con una scanf sarebbe a posto.

gets, invece, fa il contrario: non scarta nulla all'inizio ma si ferma al newline (e lo toglie dal buffer di ingresso).

Quindi la gets si trova il newline lasciato dalla precedente scanf e legge una stringa nulla. Ecco spiegato il mistero: nessun problema del compilatore per questa volta  ;D

Nota: la gets è considerata pericolosa perché non consente di specificare un numero massimo di caratteri da leggere. Lascia quindi aperta la possibilità di fornire una stringa così lunga da "bucare" qualsiasi buffer si sia allocato per contenerla.
fred_151
Prode Principiante
Messaggi: 4
Iscrizione: mercoledì 8 dicembre 2010, 18:12

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da fred_151 »

Grande Bite, grazie. La spiegazione è esaustiva. Direi che il topic è risolto, grazie a tutti!
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: GCC - errore nella compilazione quando utilizzo gets

Messaggio da bite »

bite ha scritto: scanf legge fino a un whitespace character, che in questo caso è il newline, e non lo toglie di mezzo ma lo lascia nel buffer di ingresso.
Mi accorgo che ho semplificato un po' troppo. scanf non smette di leggere solo quando incontra un whitespace, ma con qualsiasi carattere non compatibile con il formato specificato. Infatti nell'esempio di Ikitt dalla stringa "12pippo" viene letto il numero 12 con il formato %d, mentre la prima "p" di pippo, che non è compatibile con il formato intero, interrompe la lettura e viene lasciata lì. Poiché non si tratta di whitespace, la successiva gets non ha problemi a leggere "pippo": ecco perché così funziona.

Inoltre c'è da aggiungere che è possibile dire alla scanf di leggere anche i whitespace, mettendo un blank nella stringa di formato oppure usando il formato sieve: ad esempio, "%d " oppure "%d%*[\n]" toglierebbero il newline finale.

Tutte cose che puoi trovare sulla man page di scanf se hai installato il pacchetto manpages-dev.
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti