PDA

View Full Version : [C] Errore da niubbo su scanf, come lo risolvo?


c1rcu1tburn3r
24-05-2011, 11:09
Ciao, per curiosità sto leggendo il libro Kernighan e Ritchie che avevo comprato alle superiori (e mai aperto) e sto provando a scrivere un pò di codice a caso, programmini stupidi giusto per imparare ad utilizzare le varie istruzioni. Ho imparato un pò ad usare printf e scanf e a fare qualche calcolo ma sono arrivato all'ovvio errore che si ottiene quando alla richiesta di inserire un numero si inserisce invece un carattere o comunque qualcosa che non sia un numero. Capisco l'errore ma non so come gestire la cosa.
Vi metto il mio codice cosi giusto per farvi capire la demenzialità del mio livello :D
#include <stdio.h>

int main (int argc, const char * argv[])
{

float base, altezza, area;
printf("Inserisci la base del rettangolo:\n");
scanf(" %f", &base);
while (base > 99)
{
printf("Mi dispiace ma accetto solo numeri inferiori a 100... \n");
printf("Reinserire un valore da 0 a 99:\n");
scanf(" %f", &base);
}
printf("Inserisci ora l'altezza del rettangolo:\n");
scanf(" %f", &altezza);
area = base * altezza;
printf("Ho effettuato il calcolo e l'area del rettangolo risulta essere: %.2f\n", area);
return 0;
}


Leggendo qua e la leggo che scanf non è sempre il più adatto per ricevere input, ma non saprei proprio quando è o non è il caso.
Non è che magari esiste un controllo magari all'interno di un ciclo while che mi dica tipo:

while (base != numero)
{
printf("Carattere non accettato, riprovare: \n")
scanf(" %f", base);
}

No eh? :mc:
Grazie per l'aiuto!

GByTe87
24-05-2011, 11:54
Potresti usare isdigit() o atof(). :p

c1rcu1tburn3r
24-05-2011, 14:49
sto leggendo che con isdigit qualora non sia un valore numerico da valore diverso da 0...
quindi dovrei fare una cosa del tipo
if isdigit diverso da zero bla bla bla
else bla bla bla
però non capisco come scrivere il codice giusto... potresti mica farmi un esempio pratico sul mio codice? :cool:

Lazy Bit
24-05-2011, 23:06
La risoluzione del problema è abbastanza semplice. Devi pensare che ogni funzione è caratterizzata dalla seguente sintassi: tipo_restituito nome_funzione(tipo_parametro nome_parametro, ...);. Ciò prende il nome di "prototipo di funzione", che studierai più avanti, quando saprai creare tu stesso alcune funzioni.

In questo caso tu hai la funzione scanf() che ha il prototipo:

int scanf(const char *format, ...);

La funzione scanf() in caso di successo nella lettura del dato, la funzione restituisce il numero di elementi letti (infatti il tipo restituito del prototipo è un int).[/B]

Quindi, facendo un esempio:

#include <stdio.h>

int main()
{
int flag;
float number;

printf("Digitare un numero: ");
flag = scanf("%f", &number);

printf("Valore restituito dalla funzione scanf(): %d\n", flag);

return 0;
}

Se inserirai un numero, la funzione restituirà il valore 1, mentre se inserirai un carattere, la funzione restituirà 0, perché la lettura non andrà a buon fine e il contatore degli elementi letti rimarrà a zero.

c1rcu1tburn3r
27-05-2011, 18:54
Eccomi, grazie mille dei consigli... ho capito più o meno come funziona e ho provato a mettere in pratica ma non riesco a risolvere una questione...

#include <stdio.h>

int main()
{
float base;
int controllo;

printf("Digitare la base del rettangolo:\n ");
controllo = scanf(" %f", &base);
while (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
scanf(" %f", &base);
}
printf("Il numero che hai inserito è: %.2f", base);
return 0;
}


Perchè se sbaglio mi dice che ho sbagliato, ma non mi legge lo scanf per reinserire il numero? Mi manda in loop la scritta "Mi dispiace ecc..."
Eppure nel primo codice che ho postato mi funzionava... :muro:

BlackShark92
27-05-2011, 19:25
Eccomi, grazie mille dei consigli... ho capito più o meno come funziona e ho provato a mettere in pratica ma non riesco a risolvere una questione...

#include <stdio.h>

int main()
{
float base;
int controllo;

printf("Digitare la base del rettangolo:\n ");
controllo = scanf(" %f", &base);
while (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
scanf(" %f", &base);
}
printf("Il numero che hai inserito è: %.2f", base);
return 0;
}


Perchè se sbaglio mi dice che ho sbagliato, ma non mi legge lo scanf per reinserire il numero? Mi manda in loop la scritta "Mi dispiace ecc..."
Eppure nel primo codice che ho postato mi funzionava... :muro:

vai con un if...ovvero if (controllo!=1) ........
ecco, fai così
if (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
getchar();
scanf(" %f", &base);

c1rcu1tburn3r
27-05-2011, 20:14
Ho provato anche con if ma...

#include <stdio.h>

int main()
{
float base;
int controllo;

printf("Digitare la base del rettangolo:\n ");
controllo = scanf(" %f", &base);
if (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
getchar();
scanf(" %f", &base);
}
else
printf("Il numero che hai inserito è: %.2f", base);
return 0;
}


Cosi non mi va in loop e mi richiede l'input per un attimo ma poi il programma termina da solo, anche se non tocco nulla riportando:

Digitare la base del rettangolo:
e
Mi dispiace ma accetto solo numeri! Inserisci un numero:
Program ended with exit code: 0

BlackShark92
27-05-2011, 21:15
Ho provato anche con if ma...

#include <stdio.h>

int main()
{
float base;
int controllo;

printf("Digitare la base del rettangolo:\n ");
controllo = scanf(" %f", &base);
if (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
getchar();
scanf(" %f", &base);
}
else
printf("Il numero che hai inserito è: %.2f", base);
return 0;
}


Cosi non mi va in loop e mi richiede l'input per un attimo ma poi il programma termina da solo, anche se non tocco nulla riportando:

Digitare la base del rettangolo:
e
Mi dispiace ma accetto solo numeri! Inserisci un numero:
Program ended with exit code: 0

A me funziona! Comunque quello che volevi fare tu all'inizio era questo
#include <stdio.h>

int main()
{
float base;
int controllo;

printf("Digitare la base del rettangolo:\n ");
controllo = scanf(" %f", &base);
while (controllo != 1)
{
printf("Mi dispiace ma accetto solo numeri! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &base);
}
printf("Il numero che hai inserito è: %.2f", base);
return 0;
}
e adesso funziona benissimo. Sbagliavi a non riassegnare controllo dentro il while, cosicchè era sempre diversa da 1 ed entrava in un loop continuo

c1rcu1tburn3r
28-05-2011, 00:36
Ahhhh ecco perchè allora :D
Grazie mille... ora sperimento meglio e vi faccio sapere! :cool:

c1rcu1tburn3r
28-05-2011, 18:46
ihihihi che bello, inizio a trovare utilità nel programmare... proprio oggi avevo bisogno di questi calcoli e mi son fatto il programmino stupido ma pur sempre utile!

#include <stdio.h>

int main()

{
float peso, volume, diametro, raggio, altezza, area;
int controllo, controllo1;

printf("------------------------------------------------------\n");
printf("Calcolo del Volume d'acqua necessario per riempire una\n");
printf("piscina di forma tonda e del relativo peso complessivo\n");
printf("a riempimento completato.\n");
printf("------------------------------------------------------\n");

printf("Inserire il diametro interno della piscina in cm:\n");
controllo = scanf(" %f", &diametro);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &diametro);

}
printf("Inserire ora l'altezza dell'acqua in cm rispetto alla base della piscina:\n");
controllo1 = scanf(" %f", &altezza);
while (controllo1 != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo1=scanf(" %f", &altezza);

}
raggio = diametro / 2;
area = (raggio * raggio) * 3.14;
volume = (area * altezza) / 1000000;
peso = volume * 1000;

printf("Il volume di acqua necessario per riempire la piscina è di: %.2f Metri cubi\n", volume);
printf("Il peso della piscina risulterà quindi essere: %.2f Kg\n", peso);


return 0;
}


Ecco, se ora io volessi per esempio far diventare questa una funziona da richiamare all'interno di un progetto più esteso, ad esempio in un programma che proponga una scelta tra diverse forme di piscina, quindi richiamando le varie funzioni a seconda della scelta fatta, in che direzione mi conviene procedere? :cool:
So che potrei farlo direttamente con dei cicli, ma preferirei farlo con le funzioni almeno le imparo :)

c1rcu1tburn3r
28-05-2011, 19:17
Mmm, ho provato a fare cosi per ora ma non va, dove sbaglio?
Edit: Ok risolto... ci voleva un %d al posto di un %f sullo scanf dell'int scelta!!!

#include <stdio.h>

int main()

{
float peso, volume, diametro, raggio, altezza, area;
float latolungo, latocorto;
int controllo, controllo1, scelta;

printf("------------------------------------------------------\n");
printf("Calcolo del Volume d'acqua necessario per riempire una\n");
printf("piscina di forma tonda e del relativo peso complessivo\n");
printf("a riempimento completato.\n");
printf("------------------------------------------------------\n");

printf("Scegli la forma della piscina su cui fare i calcoli tra le seguenti opzioni:\n");
ricomincia:
printf("Inserire 1 se la piscina è tonda oppure \n");
printf("inserire 2 se la piscina è rettangolare: \n");
scanf(" %d", &scelta);

if (scelta == 1) //Calcolo per la piscina tonda
{
printf("Hai scelto la piscina di forma tonda\n");
printf("------------------------------------\n");
printf("Inserire il diametro interno della tua piscina in cm:\n");
controllo = scanf(" %f", &diametro);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &diametro);

}
printf("Inserire ora l'altezza dell'acqua in cm rispetto alla base della piscina:\n");
controllo1 = scanf(" %f", &altezza);
while (controllo1 != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo1=scanf(" %f", &altezza);

}
raggio = diametro / 2;
area = (raggio * raggio) * 3.14;
volume = (area * altezza) / 1000000;
peso = volume * 1000;

printf("\n\n");
printf("Il volume di acqua necessario per riempire la piscina è di: %.2f Metri cubi\n", volume);
printf("Il peso della piscina risulterà quindi essere: %.2f Kg\n", peso);
}
else if (scelta == 2) //Calcolo per la piscina rettaqngolare
{
printf("Hai scelto la piscina di forma rettangolare\n");
printf("-------------------------------------------\n");
printf("Inserire il lato più lungo della piscina in cm:\n");
controllo = scanf(" %f", &latolungo);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latolungo);

}
printf("Inserire ora il lato corto della piscina:\n");
controllo1 = scanf(" %f", &latocorto);
while (controllo1 != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo1=scanf(" %f", &latocorto);

}
printf("Inserire ora l'altezza dell'acqua in cm rispetto alla base della piscina:\n");
controllo1 = scanf(" %f", &altezza);
while (controllo1 != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo1=scanf(" %f", &altezza);

}

area = latocorto * latolungo;
volume = (area * altezza) / 1000000;
peso = volume * 1000;

printf("\n\n");
printf("Il volume di acqua necessario per riempire la piscina è di: %.2f Metri cubi\n", volume);
printf("Il peso della piscina risulterà quindi essere: %.2f Kg\n", peso);
}
else
{
printf("La scelta effettuata non rientra tra quelle possibili, riprovare:\n");
goto ricomincia;
}

return 0;
}

Ora il problema è che ho dovuto usare un GOTO per tornare alla scelta nell'ultima parte... ho letto che è sconsigliato farlo, come mai? E soprattutto, come potrei evitarlo?

BlackShark92
28-05-2011, 21:39
ihihihi che bello, inizio a trovare utilità nel programmare... proprio oggi avevo bisogno di questi calcoli e mi son fatto il programmino stupido ma pur sempre utile!

#include <stdio.h>

int main()

{
float peso, volume, diametro, raggio, altezza, area;
int controllo, controllo1;

printf("------------------------------------------------------\n");
printf("Calcolo del Volume d'acqua necessario per riempire una\n");
printf("piscina di forma tonda e del relativo peso complessivo\n");
printf("a riempimento completato.\n");
printf("------------------------------------------------------\n");

printf("Inserire il diametro interno della piscina in cm:\n");
controllo = scanf(" %f", &diametro);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &diametro);

}
printf("Inserire ora l'altezza dell'acqua in cm rispetto alla base della piscina:\n");
controllo1 = scanf(" %f", &altezza);
while (controllo1 != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo1=scanf(" %f", &altezza);

}
raggio = diametro / 2;
area = (raggio * raggio) * 3.14;
volume = (area * altezza) / 1000000;
peso = volume * 1000;

printf("Il volume di acqua necessario per riempire la piscina è di: %.2f Metri cubi\n", volume);
printf("Il peso della piscina risulterà quindi essere: %.2f Kg\n", peso);


return 0;
}


Ecco, se ora io volessi per esempio far diventare questa una funziona da richiamare all'interno di un progetto più esteso, ad esempio in un programma che proponga una scelta tra diverse forme di piscina, quindi richiamando le varie funzioni a seconda della scelta fatta, in che direzione mi conviene procedere? :cool:
So che potrei farlo direttamente con dei cicli, ma preferirei farlo con le funzioni almeno le imparo :)

se vuoi usare la funzione in un altro programma, ti basta mettere il prototipo della funzione all'inizio del file, poi nel programma la chiami come una qualunque funzione con i relativi parametri, e fuori dal main metti il corpo della funzione

Lazy Bit
29-05-2011, 00:49
Ecco, se ora io volessi per esempio far diventare questa una funziona da richiamare all'interno di un progetto più esteso, ad esempio in un programma che proponga una scelta tra diverse forme di piscina, quindi richiamando le varie funzioni a seconda della scelta fatta, in che direzione mi conviene procedere? :cool:

Dovresti creare il prototipo della tua funzione, che potresti chiamare volumePiscina(), come nell'esempio che avevo fatto precedentemente per la funzione scanf(), indicando il tipo di valore restituito e i parametri da passare. Successivamente dovrai definirla inserendo l'algoritmo, infine la chiami all'interno della main() come fai in genere con le altre funzioni. Il prototipo della tua funzione potrebbe essere:

float volumePiscina(int t, float d, float h);

c1rcu1tburn3r
29-05-2011, 09:34
Che dire... Ti vorrei come vicino di casa... :D
Il problema è che per quanto un libro sia valido non tratterà mai le cose in questo modo... I testi, anche quelli per newbie, danno per scontate cose che non lo sono e spesso e volentieri demoralizzano! E soprattutto a un libro non puoi fare domande. Secondo voi, visto il punto in cui sono, quale sarebbe il passo successivo? E delle nozioni che ho, su quali dovrei approfondire prima di passare al prossimo argomento?

Lazy Bit
29-05-2011, 11:23
Il C è un linguaggio molto potente ma è stato ideato soprattutto per fornire un efficiente e libero controllo sulla memoria. Al contrario di altri linguaggi di programmazione come il Pascal, che tendono a far concentrare il programmatore sulla risoluzione di problemi (e sono quei linguaggi utilizzati per scopi didattici), il C è orientato verso l'implementazione a diretto contatto con l'architettura del calcolatore. Se preferisci imparare prima a scrivere algoritmi, allora potresti orientarti verso un altro linguaggio, se invece vuoi imparare a programmare tenendo conto dell'architettura di un processore e della memoria, allora il C fa al caso tuo. Per quest'ultimo caso, io darei prima di tutto importanza al sistema numerico binario ed esadecimale, alla conversione tra un numero decimale e uno binario e tra un numero esadecimale e uno binario (infatti il sistema esadecimale ha la particolarità di essere un modo molto comodo di rapprentare i numeri binari). Infine studierei la rappresentazione dei numeri in un calcolatore. Poi passi alle operazioni di I/O da tastiera e ai vettori.

BlackShark92
29-05-2011, 12:18
Non posso che quotare. Insisti soprattutto con gli operatori bitwise (bit a bit, ovvero & | ecc..) così comprendi meglio le cose che ti ha detto di imparare lui. Studia bene i meccanismi di chiamata per valore e per indirizzo che è fontamentale (per quanto riguarda le funzioni), e soprattutto lavora molto con i puntatori

c1rcu1tburn3r
29-05-2011, 21:02
Fortunatamente mi ricordo abbastanza bene il sistema di numerazione binario e esadecimale e mi ricordo anche come si fanno le operazioni e le conversioni...
ricordo anche il discorso del complemento a uno e complemento a due per rappresentare i numeri negativi(anche se al momento non mi è più ben chiara la cosa, devo riguardarmela :doh: ). La tabella ascii non me la ricordo a memoria chiaramente :ciapet: ma so che i comandi, caratteri e simboli sono riconducibili a un determinato valore binario, decimale, ottale o esadecimale. Quindi so per esempio che quando premo il tasto A in realtà sto usando 01000001 in binario, giusto?

Lazy Bit
29-05-2011, 21:35
Esattamente! ;) A = 65 decimale = 01000001 binario. Comunque non intendevo dire che devi imparare a memoria l'intera tabella ASCII (ci mancherebbe! :D), l'importante che tu sappia a grandi linee come vengono rappresentati i caratteri. All'occorrenza la cerchi su Internet. ;) Per quanto riguarda la rappresentazione dei numeri in virgola mobile, potresti darci un'occhiata. Il sistema ottale non è più utilizzato perché ogni cifra rappresenta esattamente un gruppo di tre bit e ciò serve a poco, considerando che solitamente si considerano gruppi di quattro bit, rappresentati da una cifra esadecimale.

Comunque per ogni argomento che tocchi, fai esercizi. Ad esempio, sai come sono rappresentati i caratteri, il sistema di numerazione binario, conosci le istruzioni di selezione if-else e quelle di ripetizione for e while. Prova a creare una funzione uppercase() che trasformi i caratteri minuscoli in maiuscoli e una funzione lowercase() che trasformi i caratteri in minuscoli, infine una funzione decimaltobinary() che trasformi un numero decimale in binario. Quando imparerai ti potrai sbizzarrire con programmi di tua invenzione, addirittura creando una bella interfaccia grafica (GUI).

BlackShark92
29-05-2011, 21:55
Esattamente! ;) A = 65 decimale = 01000001 binario. Comunque non intendevo dire che devi imparare a memoria l'intera tabella ASCII (ci mancherebbe! :D), l'importante che tu sappia a grandi linee come vengono rappresentati i caratteri. All'occorrenza la cerchi su Internet. ;) Per quanto riguarda la rappresentazione dei numeri in virgola mobile, potresti darci un'occhiata. Il sistema ottale non è più utilizzato perché ogni cifra rappresenta esattamente un gruppo di tre bit e ciò serve a poco, considerando che solitamente si considerano gruppi di quattro bit, rappresentati da una cifra esadecimale.

Comunque per ogni argomento che tocchi, fai esercizi. Ad esempio, sai come sono rappresentati i caratteri, il sistema di numerazione binario, conosci le istruzioni di selezione if-else e quelle di ripetizione for e while. Prova a creare una funzione uppercase() che trasformi i caratteri minuscoli in maiuscoli e una funzione lowercase() che trasformi i caratteri in minuscoli, infine una funzione decimaltobinary() che trasformi un numero decimale in binario. Quando imparerai ti potrai sbizzarrire con programmi di tua invenzione, addirittura creando una bella interfaccia grafica (GUI).
questo della conversione è abbastanza complesso...occorre usare l'operazione modulo (fin qui nulla di strano), ma ciò che ritorna bisogna metterlo in un vettore e leggere al contrario il vettore!!tu come lo faresti?

c1rcu1tburn3r
29-05-2011, 21:58
questo della conversione è abbastanza complesso...occorre usare l'operazione modulo (fin qui nulla di strano), ma ciò che ritorna bisogna metterlo in un vettore e leggere al contrario il vettore!!tu come lo faresti?
Mmm credo che sia un pò troppo "oltre" questo problema per me :help:
Meglio che comincio con dell'altro mi sa eheheh

P.S. Non so se cambia qualcosa in generale ma mi sono scordato di dirvi che cmq lavoro su mac con xcode... ma credo che si dovrebbe tenerne conto solo qualora volessi sviluppare gui, giusto?

Lazy Bit
29-05-2011, 22:19
Mmm credo che sia un pò troppo "oltre" questo problema per me :help:
Meglio che comincio con dell'altro mi sa eheheh

No, diciamo che è un po' impegnativo creare l'algoritmo per la conversione di un numero decimale in binario. In effetti, come ha detto Black Shark, occorrebbe conoscere gli array per leggere al contrario i bit. Comunque prova almeno a scrivere qui le funzioni lowercase() e uppercase(). Programmare significa risolvere problemi. Cerca di capire come fare e tenta di scrivere le funzioni. Se proprio non ce la farai, ti darò qualche suggerimento. ;)

Non so se cambia qualcosa in generale ma mi sono scordato di dirvi che cmq lavoro su mac con xcode... ma credo che si dovrebbe tenerne conto solo qualora volessi sviluppare gui, giusto?
Esattamente! Le interfacce grafiche si creano appoggiandosi alle API (Application Programming Interface) fornite per il sistema operativo.

c1rcu1tburn3r
29-05-2011, 23:48
Leggendo qua e la ho forse individuato qualcosa o meglio, spero di aver capito il meccanismo di quello che ho letto.
Nel senso, con questa funzione voglio dire che:
se la variabile char x è compresa tra 97 (che sulla tabella ascii rappresenta il carattere 'a') e 122 (che rappresenta la 'z') allora, sapendo che un carattere minuscolo è distanziato dal medesimo carattere maiuscolo di 32 punti decimali, attribuisco a x un valore di x = x-32, attribuendogli di fatto il solito carattere ma maiuscolo... e simile anche per la funzione per rendere minuscolo


//Funzione che trasforma in maiuscolo
char maiuscola (char x)
{
if (x>96 && x<123)
{
x = x-32;
}

return x;
}


//Funzione che trasforma in minuscolo
char minuscola (char x)
{
if (x>64 && x<91)
{
x = x+32;
}
return x;
}

Mmm... se ho scritto stupidate non infamatemi, c'ho provato :sofico:

Lazy Bit
30-05-2011, 01:40
Bravissimo! ;) Noto che impari velocemente!

Ora ti propongo sette ulteriori esercizi, senza creare funzioni, da inserire direttamente nel main(). Risolvili quando avrai tempo e voglia. Li ho inseriti in ordine di difficoltà. Se riuscirai a risolverli tutti sarà il momento di passare allo studio degli array.

1) Scrivere un programma che legga una sequenza di lettere da tastiera e conti quante volte viene inserito il carattere 'A'. L'inserimento termina quando la somma dei codici ASCII dei caratteri inseriti supera il numero 1000.

2) Scrivere un programma che legga tre numeri positivi da tastiera che rappresentino i tre lati di un triangolo e stampi a video il tipo del triangolo (equilatero, isoscele o scaleno).

3) Scrivere un programma che chieda l'inserimento di una serie di numeri all'utente e conti quante volte è stato inserito un numero pari. L'inserimento termina quando l'utente inserisce uno zero. Stampare tanti asterischi quanti sono stati i numeri pari inseriti. Presta attenzione alla scelta dell'utilizzo dei cicli "for" e "while".

4) Scrivere un programma che legga una sequenza di n numeri (con n inserito da tastiera). Ad ogni inserimento il programma deve stampare una serie di asterischi di lunghezza pari alla somma dei numeri inseriti fino a quel momento. La somma devrà essere azzerata ogni volta che viene inserito uno zero.

5) Scrivere un programma che verifichi se l’anno inserito da tastiera è bisestile. Un anno è bisestile se è divisibile per 4 ma non per 100, fatta eccezione per gli anni divisibili per 400, che sono bisestili.

6) Scrivere un programma che dato un numero in ingresso dica se è primo. Un numero naturale è primo se non è divisibile per nessun numero intero minore di esso.

7) Scrivere un programma che calcoli la sommatoria: x^1 + x^2 + x^3 + ... + x^n, dove 'n' è un intero positivo e 'x' è un numero reale (anche negativo), entrambi dati in input dall'utente. Per il calcolo della potenza utilizzare un ciclo.

BlackShark92
30-05-2011, 18:50
Bravissimo! ;) Noto che impari velocemente!

Ora ti propongo sette ulteriori esercizi, senza creare funzioni, da inserire direttamente nel main(). Risolvili quando avrai tempo e voglia. Li ho inseriti in ordine di difficoltà. Se riuscirai a risolverli tutti sarà il momento di passare allo studio degli array.

1) Scrivere un programma che legga una sequenza di lettere da tastiera e conti quante volte viene inserito il carattere 'A'. L'inserimento termina quando la somma dei codici ASCII dei caratteri inseriti supera il numero 1000.

2) Scrivere un programma che legga tre numeri positivi da tastiera che rappresentino i tre lati di un triangolo e stampi a video il tipo del triangolo (equilatero, isoscele o scaleno).

3) Scrivere un programma che chieda l'inserimento di una serie di numeri all'utente e conti quante volte è stato inserito un numero pari. L'inserimento termina quando l'utente inserisce uno zero. Stampare tanti asterischi quanti sono stati i numeri pari inseriti. Presta attenzione alla scelta dell'utilizzo dei cicli "for" e "while".

4) Scrivere un programma che legga una sequenza di n numeri (con n inserito da tastiera). Ad ogni inserimento il programma deve stampare una serie di asterischi di lunghezza pari alla somma dei numeri inseriti fino a quel momento. La somma devrà essere azzerata ogni volta che viene inserito uno zero.

5) Scrivere un programma che verifichi se l’anno inserito da tastiera è bisestile. Un anno è bisestile se è divisibile per 4 ma non per 100, fatta eccezione per gli anni divisibili per 400, che sono bisestili.

6) Scrivere un programma che dato un numero in ingresso dica se è primo. Un numero naturale è primo se non è divisibile per nessun numero intero minore di esso.

7) Scrivere un programma che calcoli la sommatoria: x^1 + x^2 + x^3 + ... + x^n, dove 'n' è un intero positivo e 'x' è un numero reale (anche negativo), entrambi dati in input dall'utente. Per il calcolo della potenza utilizzare un ciclo.

Belli 'sti esercizi! In un quarto d'ora ho fatto il primo, il secondo ed il sesto...se riesci a fare questi, vuol dire che hai capito come usare il while e il for, ed anche alcuni trucchetti ;)

c1rcu1tburn3r
30-05-2011, 19:20
Proviamo... mia soluzione al numero 2):

#include <stdio.h>

int main ()
{
float latoa, latob, latoc;
int controllo;

printf("Inserisci la misura del lato A del triangolo:\n");
controllo = scanf(" %f", &latoa);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latoa);

}
printf("Inserisci la misura del lato B del triangolo:\n");
scanf(" %f", &latob);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latob);

}
printf("Inserisci la misura del lato C del triangolo:\n");
controllo = scanf(" %f", &latoc);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latoc);

}

if (latoa==latob && latob==latoc)
{
printf("Il triangolo in questione è un triangolo equilatero!");
}
else if (latoa==latob || latob==latoc || latoa==latoc)
{
printf("Il triangolo in questione è un triangolo isoscele!");
}
else
{
printf("Il triangolo in questione è un triangolo scaleno!");
}


return 0;
}

BlackShark92
30-05-2011, 19:28
Proviamo... mia soluzione al numero 2):

#include <stdio.h>

int main ()
{
float latoa, latob, latoc;
int controllo;

printf("Inserisci la misura del lato A del triangolo:\n");
controllo = scanf(" %f", &latoa);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latoa);

}
printf("Inserisci la misura del lato B del triangolo:\n");
scanf(" %f", &latob);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latob);

}
printf("Inserisci la misura del lato C del triangolo:\n");
controllo = scanf(" %f", &latoc);
while (controllo != 1)
{
printf("Mi dispiace ma quello che hai inserito non è un numero! Inserisci un numero:\n ");
getchar();
controllo=scanf(" %f", &latoc);

}

if (latoa==latob && latob==latoc)
{
printf("Il triangolo in questione è un triangolo equilatero!");
}
else if (latoa==latob || latob==latoc || latoa==latoc)
{
printf("Il triangolo in questione è un triangolo isoscele!");
}
else
{
printf("Il triangolo in questione è un triangolo scaleno!");
}


return 0;
}


Mi sembra giusto, solo nei controlli mettine uno anche che verifichi che il numero inserito sia positivo (non esistono triangoli con lati negativi :D ) e sono un pò dubbioso sulla condizione del triangolo isoscele...mi sembra un pò troppo generale, in quanto potrebbe valere anche se tutti e 3 sono uguali...l'hai provato?

c1rcu1tburn3r
30-05-2011, 19:35
Vero, ma a quell'else ci arriva solo se non è un triangolo equilatero :D
Diverso sarebbe stato se avessi messo prima il controllo dell'isoscele, allora si che lo avrebbe riconosciuto come triangolo isoscele anche qualora fosse un equilatero... sbaglio?

FedNat
30-05-2011, 22:48
Mi sembra giusto, solo nei controlli mettine uno anche che verifichi che il numero inserito sia positivo (non esistono triangoli con lati negativi :D ) e sono un pò dubbioso sulla condizione del triangolo isoscele...mi sembra un pò troppo generale, in quanto potrebbe valere anche se tutti e 3 sono uguali...l'hai provato?

Per la verita' manca un ulteriore controllo: verificare che i dati inseriti diano veramente un triangolo.

Esempio:
Inserendo i numeri 10, 2, 2 il programma direbbe che e' un triangolo isoscele, ma quella serie di numeri in realta' non costituisce un triangolo. Perche' tre segmenti possano costituire un triangolo occorre che ogni segmento sia minore della somma degli altri due.

Saluti

Lazy Bit
30-05-2011, 22:51
Come ha detto Black Shark, dovresti fare un controllo per verificare che i cateti del triangolo siano positivi. Anche la condizione per il triangolo isoscele non è sufficiente.

Consigli:
1) Per ottimizzare il codice e la velocità del programma, con le istruzioni di selezione if-else dovresti inserire prima sempre il caso che ha maggior probabilità di verificarsi, così il calcolatore non perde tempo a verificare anche le altre condizioni.

2) Rendi più leggibile il codice indentando bene le istruzioni. Inoltre dovresti inserire molti commenti, che spiegano quello che il blocco di codice fa.

3) Quando possibile minimizza il codice raggruppando più controlli, se ciò non va a discapito della leggibilità e comprensione del codice.

Qui posto il mio modo di risolvere il problema (con il controllo della disuguaglianza triangolare). La disuguaglianza triangolare è un teorema che dimostra che in un triangolo ogni cateto è sempre minore o uguale alla somma degli altri due.

In formula: -(|x| + |y|) <= x + y <= |x| + |y|

#include <stdio.h>

int main ()
{
float a, b, c;
int flag;

// Assegnamento valori ai cateti del triangolo
printf("Inserisci le misure dei tre cateti del triangolo: ");
flag = scanf("%f %f %f", &a, &b, &c);

// Ripetizione richiesta valori in caso di errore
while(flag == 0 || a <= 0 || b <= 0 || c <= 0)
{
printf("\nLe misure dei cateti non sono valide!\n");
printf("\nInserisci le misure dei tre cateti del triangolo: ");
getchar();

flag = scanf("%f %f %f", &a, &b, &c);
}

// Parte logica

// Disuguaglianza triangolare
if((a <= b + c) && (b <= a + c) && (c <= a + b))
{
if((a == b && a != c) || (a == c && a != b) || (b == c && b != a))
{
printf("Tipo triangolo: isoscele");
}
else if(a == b && b == c)
{
printf("Tipo triangolo: equilatero");
}
else
{
printf("Tipo triangolo: scaleno");
}
}
else
{
printf("Non e' un triangolo!");
}

printf("\n\n");

return 0;
}

Nel codice precedente, innanzitutto ho raggruppato l'input dei valori in un unico scanf(). Così da console dovranno esser inseriti i valori dei tre cateti consecutivamente, separati da uno spazio. Inoltre, se almeno uno dei valori è un carattere, la flag sarà 0. Ho anche scritto le condizioni per cui i cateti non possono aver misure negative.

Per la verita' manca un ulteriore controllo: verificare che i dati inseriti diano veramente un triangolo.Vero! La disuguaglianza triangolare! (http://it.wikipedia.org/wiki/Disuguaglianza_triangolare)

c1rcu1tburn3r
30-05-2011, 23:13
Ho capito cosa intendi... ora so che posso anche dare più valori all'interno della solita funzione scanf :)
Come fatto notare da FedNat mi servirebbe anche un controllo che verifichi se i segmenti possano realmente formare un triangolo...
dovrei aggiungere forse una roba tipo:
if (((a+b)<c) || ((a+c)<b) || ((b+c)<a)))
{
bla bla bla
}

Non so se possa essere scritto cosi :D

Lazy Bit
30-05-2011, 23:26
Mi servirebbe anche un controllo che verifichi se i segmenti possano realmente formare un triangolo...

Guarda che l'ho scritta nel codice la disuguaglianza triangolare! :Prrr:

if((a <= b + c) && (b <= a + c) && (c <= a + b))

c1rcu1tburn3r
30-05-2011, 23:35
Ops... non l'avevo mica vista quella parte di codice, forse l'hai aggiunta mentre scrivevo? :read:
Il percorso lo vedo lungo e irto, speriamo bene! Voi non mollatemi eh! :D

c1rcu1tburn3r
05-06-2011, 21:38
Raga mi date qualche indizio per il 4° esercizio? :)

Lazy Bit
05-06-2011, 21:47
Più che darti un indizio, ti porrò una domanda: per l'esercizio (4) utilizzeresti un ciclo "for" o un ciclo "while"? E perché? ;)

c1rcu1tburn3r
05-06-2011, 21:59
Mmm forse utilizzerei un ciclo for dato che gli posso dare le condizioni e l'operazione da svolgere... nel senso, credo di aver intuito che devo fare un ciclo for con all'interno solo un printf("*"); Ma non riesco a capire i parametri da mettere...per ora ho tirato fuori na roba del genere e i punti interrogativi sono quelli che ho nel cervelletto :p

#include <stdio.h>

int main ()

{
int numero, somma=0;

printf("Inserisci un numero:\n");
scanf(" %d", numero);
somma+=numero;
for (???; ????; ++?????)
{
printf("*");
}
return 0;
}

Lazy Bit
05-06-2011, 22:11
Non proprio. Il testo chiede di inserire una sequenza di numeri, ma il programma non conosce quanti sono gli elementi che tu inserirai. Quindi, dovrai utilizzare un ciclo "while". Il ciclo "for" serve per eseguire un numero definito a priori di volte un dato blocco di istruzioni; il ciclo "while", invece, si usa quando tale numero è indeterminato.

Ad esempio, tu potresti inserire la sequenza: 1 10 321 14 23 2 (quindi il tuo N sarà 6) oppure 3 5 1000 (e il tuo N sarà 3).

c1rcu1tburn3r
05-06-2011, 22:11
Ecco!!! Forse c'ho azzeccato, vedi un pò? Manca della roba, ma se non altro qualcosa vedo :)

#include <stdio.h>

int main ()

{
int numero, somma=0, i;

printf("Inserisci un numero:\n");
scanf(" %d", &numero);
while (numero!=0)
{
somma+=numero;
i=somma;
for (i=1; i<=somma; ++i)
{
printf("*");
}
scanf(" %d", &numero);
}
return 0;
}
EDIT: Non avevo capito l'esercizio... pensavo che dovessi far si che inserendo numero uno dopo l'altro il programma dovesse addizionare i numeri e raffigurare la somma con il numero di asterischi corrispondenti... :(

Lazy Bit
05-06-2011, 22:24
Però non mi quadra la condizione del while(). Comunque, l'iteratore "i" lo puoi dichiarare dentro il ciclo, così sarà una variabile locale e verrà distrutta non appena quest'ultimo terminerà.

c1rcu1tburn3r
05-06-2011, 22:27
Non ci capisco più niente :help:
Il codice che ho scritto fin'ora è quello che chiedeva l'esercizio? Apparte il fatto di azzerare nel caso in cui si inserisca 0, che non l'ho ancora fatto...

Lazy Bit
05-06-2011, 22:44
Avevi ragione tu. Rileggendo il testo, ho visto che il numero di elementi della sequenza lo devi inserire. Pardon!

Prima richiedi di quanti numeri è composta la sequenza con un primo scanf() e salvi il valore in una variabile "limite", poi richiedi di inserire la sequenza di numeri. A questo punto utilizzi un ciclo for che eseguirà il blocco tante volte quanto è il valore di "limite". Nel ciclo incrementi la variabile "somma" con il numero inserito, come hai fatto tu. Poi, con un secondo ciclo for stampi tanti * quanto è il valore della variabile "somma".

EDIT: Se vai alla pagina 3 di questo topic, ho inserito la soluzione.

Lazy Bit
05-06-2011, 22:58
#include <stdio.h>

int main()
{
int numero, somma=0, limite, i;

printf("Quanti numeri vuoi inserire? ");
scanf("%d", &limite);

printf("Inserisci numeri in sequenza: ");

for(i=0; i<limite; i++)
{
scanf("%d", &numero);
somma+=numero;
}

for(i=0; i<somma; i++)
{
printf("*");
}

printf("\n");

return 0;
}

Con uno scanf() dentro il ciclo puoi leggere tutta l'intera sequenza di numeri. Conseguentemente, puoi aggiornare la variabile "somma".

c1rcu1tburn3r
05-06-2011, 23:11
Ecco cosa non riuscivo a immaginare... lo scanf dentro al ciclo for :doh:
Sono proprio un pollo :P

Lazy Bit
05-06-2011, 23:23
Tranquillo, i cicli for sono pericolosi! Io ho combinato parecchi danni anni addietro! :D

Se hai bisogno di una mano per altri esercizi, chiedi pure.

c1rcu1tburn3r
05-06-2011, 23:49
:ave:
Per il primo esercizio? Che direzione dovrei prendere?

Lazy Bit
05-06-2011, 23:53
Dovrebbe essere dello stesso tipo del 4°. Solo che al posto dei numeri devi sommare i caratteri. Un carattere ASCII è un numero. :)

FedNat
06-06-2011, 09:32
#include <stdio.h>

int main()
{
int numero, somma=0, limite, i;

printf("Quanti numeri vuoi inserire? ");
scanf("%d", &limite);

printf("Inserisci numeri in sequenza: ");

for(i=0; i<limite; i++)
{
scanf("%d", &numero);
somma+=numero;
}

for(i=0; i<somma; i++)
{
printf("*");
}

printf("\n");

return 0;
}

Con uno scanf() dentro il ciclo puoi leggere tutta l'intera sequenza di numeri. Conseguentemente, puoi aggiornare la variabile "somma".

Scusa, ma non mi sembra che questo codice rispetti le specifiche del quesito proposto. Il ciclo for di stampa degli asterischi dovrebbe stare annidato nel ciclo for di immissione numeri inltre dovrebbe esseric la condizione di azzermento della somma.

Provo a buttarlo giu' al volo, potrebbero esserci errori:
#include <stdio.h>

int main()
{
int numero, somma=0, limite, i, j;

printf("Quanti numeri vuoi inserire? ");
scanf("%d", &limite);

printf("Inserisci numeri in sequenza: ");

for(i=0; i<limite; i++)
{
scanf("%d", &numero);
if (numero != 0)
somma+=numero;
else
somma = 0;

for(j=0; j<somma; j++)
{
printf("*");
}
printf("\n");
}


printf("\n");

return 0;
}

Lazy Bit
06-06-2011, 12:16
Inoltre dovrebbe esserci la condizione di azzermento della somma.
Hai ragione! Comunque avevo scritto solo un esempio per far comprendere il modo in cui la sequenza di numeri veniva sommata in una variabile. :)