View Full Version : [C] Problemino
InferNOS
29-03-2007, 12:20
Ciao raga..ho fatto un programmino stupidissimo (abbiamo appena iniziato all'uni..) e vorrei ke windows nn mi chiudesse subito la finestra del dos una volta eseguito il programma..allora cercando su internet ho trovato la funzione system("PAUSE")..ma vorrei chiedervi alcune cose a riguardo..si dice ke x farla funzionare bisogna includere la libreria <stdlib.h> ma a me funziona lo stesso senza (e premetto ke l unica ke ho incluso è <stdio.h>) inoltre dopo la funzione va messo return 0..cosa vuol dire ke la funzione restuisce 0??
grazieee
PS:di sicuro avrò altre domande in futuro..qnd posterò direttamente qua..:)
Ciao raga..ho fatto un programmino stupidissimo (abbiamo appena iniziato all'uni..) e vorrei ke windows nn mi chiudesse subito la finestra del dos una volta eseguito il programma..allora cercando su internet ho trovato la funzione system("PAUSE")..ma vorrei chiedervi alcune cose a riguardo..si dice ke x farla funzionare bisogna includere la libreria <stdlib.h> ma a me funziona lo stesso senza (e premetto ke l unica ke ho incluso è <stdio.h>) inoltre dopo la funzione va messo return 0..cosa vuol dire ke la funzione restuisce 0??Innanzitutto per il "pause" leggi <questo> (http://www.hwupgrade.it/forum/showthread.php?t=1323690) thread. ;)
Il valore ritornato dal main() può essere utile al processo "padre" per determinare l'esito del programma. Ora ... non c'è una regola precisa su cosa restituire. Sui sistemi Linux/Unix dove si usano molto le shell e dove spesso si ha bisogno di conoscere l'esito di un programma, la convenzione è che uno status=0 significa successo e altri valori significano fallimento o comunque una qualche altra segnalazione.
InferNOS
29-03-2007, 15:18
Innanzitutto per il "pause" leggi <questo> thread.
Il valore ritornato dal main() può essere utile al processo "padre" per determinare l'esito del programma. Ora ... non c'è una regola precisa su cosa restituire. Sui sistemi Linux/Unix dove si usano molto le shell e dove spesso si ha bisogno di conoscere l'esito di un programma, la convenzione è che uno status=0 significa successo e altri valori significano fallimento o comunque una qualche altra segnalazione.
OK grazie..xò ancora nn ho chiaro cm mai system("PAUSE") mi funziona anche senza includere librerie aggiuntive e nemmeno senza mettere il return 0..ossia nel mio programma all'ultima riga metto system("PAUSE") dopodichè chiudo la graffa e funge uguale..x qll mi chiedevo a cosa servisse il return (qnd anche senza funziona) e soprattutto senza includere <stlib>..boh
OK grazie..xò ancora nn ho chiaro cm mai system("PAUSE") mi funziona anche senza includere librerie aggiuntive e nemmeno senza mettere il return 0..ossia nel mio programma all'ultima riga metto system("PAUSE") dopodichè chiudo la graffa e funge uguale..x qll mi chiedevo a cosa servisse il return (qnd anche senza funziona) e soprattutto senza includere <stlib>..bohAllora partiamo dal return. Il main deve ritornare un int, la sua dichiarazione tipicamente può essere:
int main (void)
oppure
int main (int argc, char *argv[])
Il valore restituito, come ho già detto, è lo "status" del programma (e non c'entra nulla con una system() ).
Passiamo a system(). Il suo prototipo in stdlib.h è un qualcosa del tipo int system(const char*).
Ora ... il valore di ritorno di system non lo usi e comunque system ritorna un int (la regola è che se una funzione non è dichiarata precedentemente, viene implicitamente presa come una funzione che ritorna un int e senza fare assunzioni sui parametri).
Quindi anche senza prototipo e finché passi un puntatore a char a system, va tutto bene. In ogni caso la fase di linking è ok, perché il linker comunque linka con la libreria standard.
Il prototipo serve appunto per far sì che il compilatore possa controllare/convertire gli argomenti passati. Se non includi stdlib.h e fai:
system (123456);
Il compilatore non fa obiezioni (al massimo potrebbe dire che system non è definita) ... ma se lo esegui ... molto probabilmente va in crash!! Se invece includi stdlib.h ti segnalerà un chiaro warning del fatto che hai passato un argomento non corretto.
Molto probabilmente il programma funziona anche senza includere la stdio.h.
Questo è opera del compilatore che usi, che include automaticamente le librerie principali come la stdio e la stdlib.
Gcc fa questo.
Altrimenti può essere come ha detto andbin.
Daniel
InferNOS
07-04-2007, 17:59
Ciao ragà..vorrei chiedervi una cosa sullo switch-case..allora ho fatto un programma in cui scelgo tre possibile vie da percorrere..ok fin qui tutto bene..xo una volta scelta una delle tre opzioni svolgo quella specifica opzione e il programma finisce..se volessi ke tornasse di nuovo a chiedere quali opzione scegliere?Ho pensato ad un ciclo for x far ripetere il programma finkè nn sia io ad chiedergli di uscire..ebbene ecco il listato ma nn va cm vorrei io..dv è l'errore?
#include <stdio.h>
char scelta;
main()
{
printf("\t\t\t\tCALCOLI GEOMETRICI\n");
for( ; ; ){
printf("\na)Trasposta di una matrice.\nb)Somma di due matrici.\n");
printf("c)Prodotto di due matrici.\ne)Exit.\n");
printf("\nScegli tra le opzioni: ");
scelta = getchar();
switch(scelta) {
case 'a':
printf("Hai scelto a\n");
break;
case 'b':
printf("Hai scelto b\n");
break;
case 'c':
printf("Hai scelto c\n");
break;
case 'e':
exit(0);
default:
printf("Selezione errata!\n");
break;
}
}
}
Ciao ragà..vorrei chiedervi una cosa sullo switch-case..allora ho fatto un programma in cui scelgo tre possibile vie da percorrere..ok fin qui tutto bene..xo una volta scelta una delle tre opzioni svolgo quella specifica opzione e il programma finisce..se volessi ke tornasse di nuovo a chiedere quali opzione scegliere?Ho pensato ad un ciclo for x far ripetere il programma finkè nn sia io ad chiedergli di uscire..ebbene ecco il listato ma nn va cm vorrei io..dv è l'errore?L'errore è che non sai come funziona getchar(). È "bufferizzata", ritorna il carattere solo dopo che hai premuto 'invio'. Ma se premi 'a' e poi 'invio' la getchar() ritorna giustamente la 'a' ma il '\n' rimane nel buffer e viene ritornato subito dalla successiva getchar()!!
Altre quisquilie: getchar() ritorna un int, non un char, quindi scelta dichiaralo come int. Inoltre includi <stdlib.h>
InferNOS
07-04-2007, 18:38
L'errore è che non sai come funziona getchar(). È "bufferizzata", ritorna il carattere solo dopo che hai premuto 'invio'. Ma se premi 'a' e poi 'invio' la getchar() ritorna giustamente la 'a' ma il '\n' rimane nel buffer e viene ritornato subito dalla successiva getchar()!!
Altre quisquilie: getchar() ritorna un int, non un char, quindi scelta dichiaralo come int. Inoltre includi <stdlib.h>
Quindi cm fare ad iterare nel modo giusto qst programmino??Cmq avevo usato anche scanf al posto di getchar ma il problema era lo stesso..poi xkè includere stdlib?
qst il prog cn scanf:
#include <stdio.h>
#include <stdlib.h>
char scelta;
main()
{
printf("\t\t\t\tCALCOLI GEOMETRICI\n");
for( ; ; ){
printf("\na)Trasposta di una matrice.\nb)Somma di due matrici.\n");
printf("c)Prodotto di due matrici.\ne)Exit.\n");
printf("\nScegli tra le opzioni: ");
scanf("%c", &scelta);
switch(scelta) {
case 'a':
printf("Hai scelto a\n");
break;
case 'b':
printf("Hai scelto b\n");
break;
case 'c':
printf("Hai scelto c\n");
break;
case 'e':
exit(0);
default:
printf("Selezione errata!\n");
break;
}
}
}
Quindi cm fare ad iterare nel modo giusto qst programmino?? Cmq avevo usato anche scanf al posto di getchar ma il problema era lo stesso..while (getchar() != '\n');
messo dopo l'input, in modo da "buttare" via tutto il rimanente fino al \n.
poi xkè includere stdlib?Per la exit().
Puoi risolvere benissimo pulendo il buffer prima di chiamare la getchar
#include <stdio.h>
int main()
{
char scelta;
printf("CALCOLI GEOMETRICI\n");
for ( ; ; ) {
printf("\n"
"a)Trasposta di una matrice.\n"
"b)Somma di due matrici.\n"
"c)Prodotto di due matrici.\n"
"e)Exit.\n");
printf("\nScegli tra le opzioni: ");
fflush(stdin); // pulisce il buffer sulla stdin
scelta = getchar();
switch(scelta) {
case 'a':
printf("Hai scelto a \n");
break;
case 'b':
printf("Hai scelto b \n");
break;
case 'c':
printf("Hai scelto c \n");
break;
case 'e':
return 0;
break;
default:
printf("Selezione errata! \n");
break;
}
} // fine for
} // fine main()
Daniel
Oppure puoi fare tutto usando un ciclo do-while che qualsiasi prof. di "Fondamenti di informatica/programmazione" o "Informatica 1" gradisce maggiormente. ;)
#include <stdio.h>
#include <stdlib.h>
int main() {
int select ;
printf("CALCOLI GEOMETRICI\n") ;
do {
printf(
"\n"
"a) Trasposta di una matrice.\n"
"b) Somma di due matrici.\n"
"c) Prodotto di due matrici.\n"
"e) Esci.\n"
) ;
select = getchar() ;
/* Pulizia buffer di ingresso */
while(getchar() != '\n') ;
switch(select) {
case 'a':
printf("Hai scelto a!\n") ;
break ;
case 'b':
printf("Hai scelto b!\n") ;
break ;
case 'c':
printf("Hai scelto c!\n") ;
break ;
case 'e':
break ;
default:
printf("Errore!");
break ;
}
} while(select != 'e') ;
return(0) ;
}
Oppure puoi fare tutto usando un ciclo do-while che qualsiasi prof. di "Fondamenti di informatica/programmazione" o "Informatica 1" gradisce maggiormente. ;)
Ne terrò conto poi per l'Università :D :D
fflush(stdin); // pulisce il buffer sulla stdinfflush() è fatta per stream di output. Il comportamento non è predefinito, a livello di standard, per stream di input (sebbene su certi compilatori, es. VC++, pulisca correttamente il buffer di input).
InferNOS
09-04-2007, 22:52
Ciao raga..grazie x le risp..qst giorni nn c sono stato..
allora avrei una domanda x sirus..mi spiega meglio un pò cosa hai fatto??:p
Allora innanzitutto xkè nn usare un semplice while?dopodikè nel do-while mi sarei aspettato un do all'inizio del blocco e un while alla fine mentre qui ce ne sono due(???)..cm mai?:muro:
Ciao raga..grazie x le risp..qst giorni nn c sono stato..
allora avrei una domanda x sirus..mi spiega meglio un pò cosa hai fatto??:p
Allora innanzitutto xkè nn usare un semplice while?dopodikè nel do-while mi sarei aspettato un do all'inizio del blocco e un while alla fine mentre qui ce ne sono due(???)..cm mai?:muro:Nel codice di sirus c'è 1 solo do-while, è quello:
do {
printf(
"\n"
"a) Trasposta di una matrice.\n"
......
}
} while(select != 'e') ;L'uso di un do-while, piuttosto che un while, è abbastanza logico ... l'input della scelta lo devi fare almeno 1 volta.
All'interno di quel ciclo c'è un while, che non centra nulla con il do-while principale:
while(getchar() != '\n') ;che come ho già detto anche io, serve solo per "buttare" via i caratteri rimasti nel buffer di input. Il ';' alla fine del while non deve confondere .... è solo per indicare una istruzione "vuota".
InferNOS
10-04-2007, 09:35
OK grazie andbin...era quel punto e virgola ke non riuscivo a capire..ora mi è molto + chiaro tutto il codice..un ultima cosa..nel while(esp) si verifica l 'espressione dopodichè se risulta vera si esegue l'istruzione..qui ke l'istruzione non c'è cosa fa esattamente il programma??Ossia a parole ke gli dice di fare al prog?
Es.. while(n!=0){
printf("Ciao")
} qui nel caso ke n è diverso da 0 il prog stampera ciao senno si blocca
ma qui while(getchar() != '\n') ; cosa viene chiesto di fare?finchè l'utente nn spinge invio ke succede?
scusa se vi sto rompendo ma vorrei capire x benino sti cavolo di costrutti!:muro:
ma qui while(getchar() != '\n') ; cosa viene chiesto di fare?finchè l'utente nn spinge invio ke succede?
scusa se vi sto rompendo ma vorrei capire x benino sti cavolo di costrutti!:muro:Riprendiamo il pezzo di codice:
select = getchar() ;
while(getchar() != '\n') ;Sei nella prima getchar(), supponiamo che tu digiti 'a' poi 'b' e poi Invio. Nel buffer hai 3 caratteri: 'a', 'b' e '\n' (che è l'invio). La 'a' viene restituita dalla getchar(), gli altri 2 rimangono nel buffer di input.
La while con getchar semplicemente cicla finché la getchar restituisce \n, quindi appunto legge tutti i caratteri rimasti nel buffer. Il corpo del while non deve fare nulla (da qui il ';' come istruzione nulla).
mapomapo
10-04-2007, 09:43
allora penso che il problema a livello concettuale sia il seguente (l'ho avuto anche io qualche mesetto fa):
select = getchar() ;
/* Pulizia buffer di ingresso */
while(getchar() != '\n') ;
qui semplicemente si dice "assegna a select un carattere preso in input finchè (while) questo carattere è diverso da invio (\n)"
in pratica quando viene eseguita la getchar() [dovrebbe essere come una scanf("%c", &select);], ammettendo che tu voglia scegliere il carattere 'a', dovrai per forza di cose, sulla tastiera, pigiare prima la 'a' e dopo invio ('\n')...così facendo in memoria rimane il carattere '\n' e quindi entri nel case:default dello switch
spero di essere stato chiaro.... :)
Vito
InferNOS
10-04-2007, 10:01
Chiarissimo ragazzi!! C'è un xò (ke rompi coglioni ke sono è?:D )..così come è il codice va bene qnd l'utente digita..una lettera e poi preme invio..se invece l'utente è scemo e digita "agbssdfd"..il programma risponde cmq "hai scelto a" xkè è letta solo la prima lettera del getchar..questo cm si dovrebbe risolvere?
Chiarissimo ragazzi!! C'è un xò (ke rompi coglioni ke sono è?:D )..così come è il codice va bene qnd l'utente digita..una lettera e poi preme invio..se invece l'utente è scemo e digita "agbssdfd"..il programma risponde cmq "hai scelto a" xkè è letta solo la prima lettera del getchar..questo cm si dovrebbe risolvere?Non puoi fare altrimenti ... la while(getchar() != '\n'); serve proprio a buttare via i caratteri superflui.
Immagina che non ci sia questo ciclo, se la prima volta premi 'abc' e invio, la prima selezione è ok ('a'), i successivi 2 cicli la selezione è ancora ok ma NON si ferma per l'input, e per l'ultimo carattere restituito cioè \n, andrebbe nel caso default.
Non è certo un buon comportamento!
in pratica quando viene eseguita la getchar() (dovrebbe essere come una scanf("%c", &select);), ammettendo che tu voglia scegliere il carattere 'a', dovrai per forza di cose, sulla tastiera, pigiare prima la 'a' e dopo invio ('\n')...così facendo in memoria rimane il carattere '\n' e quindi (se non ci fosse il ciclo di pulizia del buffer di ingresso, nel ciclo successivo il programma non eseguirebbe nessuna richiesta di input ma preleverebbe direttamente il carattere dal buffer. nds) entri nel case:default dello switch.
spero di essere stato chiaro.... :)
Vito
Quelle 2 righe di codice sono state ampiamente spiegate quindi è inutile che lo rifaccia. Quello che vorrei far notare che anche l'utilizzo della scanf() sui char comporta dei problemi simili a quelli che abbiamo trattato in questo thread.
Supponiamo di leggere un int facendo uso di una scanf() e successivamente di voler leggere un char sempre usando una scanf(). La seconda scanf() riporterebbe il carattere '\n' trascurato dalla prima. :muro:
Se non vado errando l'istruzione che risolve il problema è quelcosa di simile a questa:scanf("%c%*c",&select) ;:p
Quindi il codice di acquisizione che ho descritto nelle righe sopra verrebbe:scanf("%d",&primo) ;
scanf("%c%*c",&secondo) ;
provare per credere. :D
Chiarissimo ragazzi!! C'è un xò (ke rompi coglioni ke sono è?:D )..così come è il codice va bene qnd l'utente digita..una lettera e poi preme invio..se invece l'utente è scemo e digita "agbssdfd"..il programma risponde cmq "hai scelto a" xkè è letta solo la prima lettera del getchar..questo cm si dovrebbe risolvere?
Potresti pensare di aggiungere un contatore nel ciclo di pulitura del buffer invece dell'istruzione nulla. Se al termine il contatore è nullo allora il carattere acquisito è valido (è stato scartato solo un INVIO) altrimenti significa che l'input è stato "falsato". ;)
#include <stdio.h>
#include <stdlib.h>
int main() {
int select ;
int cnt ;
printf("CALCOLI GEOMETRICI\n") ;
do {
do {
printf(
"\n"
"a) Trasposta di una matrice.\n"
"b) Somma di due matrici.\n"
"c) Prodotto di due matrici.\n"
"e) Esci.\n\n"
) ;
select = getchar() ;
/* Pulizia buffer di ingresso */
cnt = 0 ;
while(getchar() != '\n') cnt++ ;
if(cnt != 0)
printf("\nInput errato! Ripetere l'acquisizione\n") ;
} while(cnt != 0) ;
switch(select) {
case 'a':
printf("\nHai scelto a!\n") ;
break ;
case 'b':
printf("\nHai scelto b!\n") ;
break ;
case 'c':
printf("\nHai scelto c!\n") ;
break ;
case 'e':
break ;
default:
printf("\nErrore!");
break ;
}
} while(select != 'e') ;
return(0) ;
}
NB: ricorda che questi sono comportamenti che vanno documentati all'utente. :D
InferNOS
10-04-2007, 14:17
Grazie a tutti..penso e spero di aver capito..:)
PS:nn pensate di esserevi liberati tanto facilmente di me..:D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.