PDA

View Full Version : [C] Uso di scanf() per input diversi di volta in volta


ka0s
31-01-2007, 11:52
Ho bisogno di usare scanf per poter leggere, di volta in volta, input che potrebbero essere differenti... mi spiego meglio:

La prima volta l'utente potrebbe inserire '1' e viene chiamata la funzione 1 del programma, al termine di essa si richiede di nuovo l'input. A questo punto l'utente potrebbe inserire "2 a b", quindi viene chiamata la funzione 2 ma vengono gestiti anche i parametri a e b che potrebbero essere caratteri, stringhe, ecc. Oppure potrebbe scrivere 'q' per far terminare il programma, ecc. ecc. E' possibile farlo con una sola scanf e poi elaborare ciò che è stato inserito in maniera differente a seconda dei vari casi? (ovviamente tutti i possibili casi sono già noti)

Griffo
31-01-2007, 12:22
Non ricordo bene la sintassi del c tuttavia potresti assegnare ad una varibile di tipo string il valore ricevuto da scanf e poi valutarla con un if, magari il tutto dentro un ciclo while per valutare l'uscita del ciclo (se la string è ugulae a "q")...

ka0s
31-01-2007, 12:47
Però io ho bisogno di manipolare separatamente tutti i parametri che l'utente inserisce... voglio dire, se viene inserito un numero, una stringa e un carattere (si intende sempre che questa "combinazione" sia prevista dal programma e che i vari parametri siano separati da spazi o da trattini o da altro) dovrò poter gestire questi tre valori in modo separato... allo stesso tempo però deve essere possibile inserire prima un carattere, poi una stringa e poi un numero, ecc. ecc.

spero di essermi spiegato (in poche parole il programma non dispone di un menu, ma viene fatta una "selezione" al momento dell'input ed in base all'input)

yorkeiser
31-01-2007, 14:02
Usa la funzione gets al posto di scanf

char* stringa;
stringa=(char*)malloc(MAX_LUNGHEZZA);
gets(stringa);


A quel punto dividi la stringa in base agli spazi inseriti e implementi la logica che preferisci

RaouL_BennetH
31-01-2007, 14:23
Usa la funzione gets al posto di scanf

char* stringa;
stringa=(char*)malloc(MAX_LUNGHEZZA);
gets(stringa);


A quel punto dividi la stringa in base agli spazi inseriti e implementi la logica che preferisci

Non so se parlo a proposito, ma dovunque mi giro e mi documento leggo che "gets" dovrebbe essere evitata come la peste a causa del fatto che non si può limitare l'effetto di una stringa inserita più lunga di quella consentita. Da quel pochissimo che so, leggo sempre che si dovrebbe utilizzare fgets al posto di gets.

Scusami in anticipo se ho detto stupidaggini.

Per Kaos: l'utilizzo di "case" non potrebbe risolverti il problema?

yorkeiser
31-01-2007, 14:36
Non so se parlo a proposito, ma dovunque mi giro e mi documento leggo che "gets" dovrebbe essere evitata come la peste a causa del fatto che non si può limitare l'effetto di una stringa inserita più lunga di quella consentita. Da quel pochissimo che so, leggo sempre che si dovrebbe utilizzare fgets al posto di gets.

Scusami in anticipo se ho detto stupidaggini.


Non hai detto stupidaggini: se prevedi di usare stringhe lunghe hai ragione, l'uso di fgets sulla STDIN al posto di gets è vivamente consigliabile, come hai rimarcato. Nel caso di un programma che non sembra dover leggere stringhe lunghe, come quello proposto da ka0s - almeno dagli esempi di utilizzo che ne ha suggerito - puoi tranquillamente usare la gets: non corri il rischio di andare in overflow sullo stack per qualche carattere inserito ;)
Comunque, in linea di massima, la fgets è certamente più 'sicura' della gets

ka0s
31-01-2007, 14:58
grazie per le risposte :)

però ho bisogno di spiegazioni aggiuntive... una volta acquisita la stringa con gets (o fgets) come si fa a manipolarla?

non c'è proprio un modo per fare lo stesso ma usando scanf ?

Per RaouL_BennetH: con "case" intendi il costrutto switch ?

Ziosilvio
31-01-2007, 15:13
Ho bisogno di usare scanf per poter leggere, di volta in volta, input che potrebbero essere differenti
Allora hai bisogno di fgets, non di scanf.
scanf si aspetta un input organizzato secondo un certo formato: ad esempio, una parola seguìta da due numeri.
fgets non fa questa assunzione, e prende la stringa così com'è, lasciando a te l'incarico di manipolarla in sèguito.
E' possibile farlo con una sola scanf e poi elaborare ciò che è stato inserito in maniera differente a seconda dei vari casi? (ovviamente tutti i possibili casi sono già noti)
Potresti provare a usare strtok per manipolare la stringa; ma è una funzione che io non ho mai usato, e non ti so aiutare.

RaouL_BennetH
31-01-2007, 16:47
grazie per le risposte :)

però ho bisogno di spiegazioni aggiuntive... una volta acquisita la stringa con gets (o fgets) come si fa a manipolarla?

non c'è proprio un modo per fare lo stesso ma usando scanf ?

Per RaouL_BennetH: con "case" intendi il costrutto switch ?

Si :( scusami per il modo poco preciso di indicarlo

ka0s
03-02-2007, 11:12
pensavo di controllare il primo carattere della stringa inserita e poi operare di conseguenza... solo che non so bene come fare...

se io inserisco come input: "1 stringa1 stringa2"
il programma deve fare un qualcosa (il valore '1' indica ad es. una specifica funzione) con le due stringhe, che ovviamente vanno trattate separatamente... idem se invece delle stringhe ci fossero numeri.

mapomapo
03-02-2007, 12:14
usa una funzione di questo tipo:

int menu()
{
int choice;

printf("Prego effettuare una scelta:\n");
printf("1. Inserire un nuovo elemento\n");
printf("2. Stampare la lista\n");
printf("0. Esci dal programma\n"); //Tu qui specifica i vari input dell'utente
scanf("%d", &choice);
return choice;
}

nel main invece avrai una cosa di questo tipo:

do
{
scelta=menu();

switch(scelta)
{
case 1:
{
printf("Categoria: ");
scanf("%s", category);
printf("Nome prodotto: ");
scanf("%s", productname);
printf("Prezzo: ");
scanf("%f", &money);

ins_centro(&testa,category,productname,money);
}
break;

case 2:
{
stampa_lista(testa);
}
break;
default:break;
}
}while(scelta!=0);


ovviamente il mio codice viene da un programma completamente diverso, ma spero di averti dato uno spunto :)

Vito

cionci
03-02-2007, 13:11
Se l'utente inserisce:

1 ab cd[seguiti da INVIO]

I caratteri 1[spazio]ab[spazio]cd[INVIO] rimangono nel buffer di input fino a quando non vengono rimossi...

Puoi anche leggerli con scanf diverse...ad esempio:

scanf("%d", &scelta); /* rimuove i 1[spazio] */

if(scelta == 1) funzione1();

...

void funzione1()
{
char param1[MAX_BUF], param2[MAX_BUF];
scanf("%s", param1); /* rimuove ab[spazio] */
scanf("%s", param2); /* rimuove cd[invio] */
....
}

Quindi per gestire l'inserimento separato da spazi non devi fare assolutamente niente...la gestione è la stessa che attueresti nel caso l'inserimento fosse separato da [invio].

ka0s
03-02-2007, 13:11
grazie mapomapo!
il problema è che una cosa del genere sapevo già farla, mentre ora devo fare in modo che l'input sia una sola linea per volta. Quindi il programma dopo non deve chiedere altre cose.

la difficoltà sta proprio nel realizzare questo procedimento!

EDIT: cionci, abbiamo postato praticamente insieme ;) cmq adesso provo la tua idea (non sapevo che si potesse fare una cosa del genere!!)

cionci
03-02-2007, 13:17
Ah...togli la & dalle ultime due scanf...errore di copia e incolla ;)