PDA

View Full Version : [C] Funzione con valore sentinella non rilevato


Composition86
06-11-2008, 22:53
Salve a tutti, mi potreste dire cosa c'è di errato in questa funzione?
void digitaVettore (char v[])
{
int i=0;

printf ("Digita una serie di caratteri (numeri, lettere e simboli); "
"inserisci il carattere '!' per terminare.\n");

do {
scanf ("%s", &v[i]);
i++;
} while (v[i] != '!');

i=0;

printf ("Ecco la stringa inserita:\n");

while (v[i] != '!') {
printf ("%s", v[i]);
i++;
}
}
Il programma completo funziona correttamente, ma in entrambi i casi in cui ho utilizzato il valore sentinella (sia col "while" che col "do/while" questo non viene rilevato). Grazie in anticipo.

gugoXX
06-11-2008, 23:38
Perche' quando arrivi a valutare

} while (v[i] != '!');

La i e' gia' incrementata, e quindi non c'e' piu' il ! appena inserito, ma cio' che c'era originariamente nel buffer in questa nuova posizione, che verra' presto sostituito dal prossimo valore inserito.

Composition86
06-11-2008, 23:53
Vero, mi era sfuggito. Ti ringrazio!

cionci
07-11-2008, 09:08
Per leggere caratteri si usa %c, non %s.

Composition86
07-11-2008, 11:06
Per leggere caratteri si usa %c, non %s.
Ti ringrazio, funziona. Ma sinceramente non mi è molto chiara la differenza tra i due.
Perchè devo utilizzare %c e non %s. Quando avrei potuto utilizzare %s?

EDIT Nel caso del programma in questione vorrei far notare che devo inserire lettere, numeri e simboli.

cionci
07-11-2008, 11:40
Ti ringrazio, funziona. Ma sinceramente non mi è molto chiara la differenza tra i due.
Perchè devo utilizzare %c e non %s. Quando avrei potuto utilizzare %s?

EDIT Nel caso del programma in questione vorrei far notare che devo inserire lettere, numeri e simboli.
Quello che vuoi fare è leggere carattere per carattere (lettere, numeri e simboli), giusto ?
Un carattere con scanf si legge con %c e non con %s, con %s si legge una stringa fino all'invio.
Sinceramente non capisco perché funzionasse prima. Dovrebbe andare in ciclo infinito fino a fare un buffer overflow.

Composition86
07-11-2008, 13:15
Credo di aver capito la differenza, mi ero perso un paio di cose, faccio un elenco, potrà servire a qualcuno che fa una ricerca nel forum:

-la funzione gets(vettore) legge una stringa fino al primo invio.
-scanf(%s, vettore) legge fino al primo invio, spazio o tabulazione.
-lettura carattere per carattere, metodo decisamente scomodo.

Riguardo al tuo "dubbio", non so neanche io perchè prima funzionasse, forse avevo lasciato qualche %c o %s non voluto.

cionci
07-11-2008, 13:47
-lettura carattere per carattere, metodo decisamente scomodo.
Anche perché lo stdin del C è bufferizzato, quindi il controllo torna al programma solo alla pressione del tasto invio.
Per avere un stdin non bufferizzato - leggi: premo un carattere, il programma legge il carattere e su questo carattere posso eseguire subito delle operazioni prima della lettura successiva - si può avere solo con librerie non standard o comunque dipendenti dal sistema operativo.

Composition86
07-11-2008, 14:40
Ti ringrazio ancora, ho capito.

Però mi è venuto un altro dubbio a proposito di %c e %s, devo leggere una variabile di tipo char (quindi nelle dichiarazioni ho "char carattere"); uso questa operazione:

scanf ("%c", &carattere);

In lettura devo mettere %s al posto di %c per farlo funzionare (e non me lo spiego), mentre se voglio stampare il carattere devo mettere %c e non %s, altrimenti il programma si blocca.