Sottoprogramma in C...
ciao a tutti devo fare un programma all'apparenza semplice, cioè scrivere un prog che letto da tastiera una data mi dice se la data è esatta.... non devo usare la funzione per le date nemmeno i puntatori o i vettori...
io il programma l'ho scritto però non funziona bene... questo è il codice:
solo che non funziona correttamente se metto la data 31/3/1990 non funziona (l'anno è irrilevante può anche essere un altro anno qualsiasi)...
io credo che è sbagliata l'istruzione
io il programma l'ho scritto però non funziona bene... questo è il codice:
#include <stdio.h> #include <stdlib.h> int data_esatta (int g, int m, int a); main (){ int g,m,a; int data_corretta; printf ("inserisci il giorno mese e l'anno: "); scanf ("%d,%d,%d",&g,&m,&a); data_corretta = data_esatta(g,m,a); printf("la data iserita e' correta."); system ("PAUSE"); } /*funzione*/ int data_esatta (int gg, int mm, int aa){ do { printf ("inserisci il giorno mese e l'anno: "); scanf("%d,%d,%d", &gg,&mm,&aa); } while (((gg<0)||(mm<0)||(aa<0))||((gg>31)||(mm>12)||(aa>2011))); if (mm =! 2) { if( (mm==11 || mm==4 || mm==6 || mm==9) && (gg<=30) || (mm==11 || mm==4 || mm==6 || mm==9) && (gg<=31) ) printf("la data e' esatta."); } else{ if ( aa % 400==0 || aa % 4==0 && !(aa % 100==0)){ do{ printf ("inserisci il giorno mese e l'anno: "); scanf("%d,%d,%d", &gg,&mm,&aa); } while (gg>29); printf("la data e' corretta.");} else { do{ printf ("inserisci il giorno mese e l'anno: "); scanf("%d,%d,%d", &gg,&mm,&aa); } while (gg>28); printf ("la data è corretta."); } } }
solo che non funziona correttamente se metto la data 31/3/1990 non funziona (l'anno è irrilevante può anche essere un altro anno qualsiasi)...
io credo che è sbagliata l'istruzione
(mm==11 || mm==4 || mm==6 || mm==9) && (gg<=30) || (mm==11 || mm==4 || mm==6 || mm==9) && (gg<=31)
Risposte
L'errore non è in quella riga.
Un primo errore che è invece immediatamente visibile è l'uso di =! invece che di != nella seguente riga:
Immagino volessi scrivere
Ci sono poi degli errori nel modo in cui hai scritto la funzione. In particolare:
1. La lettura della data avviene sia nel main che nella funzione data_esatta.
2. Il tuo programma non fa quello che gli è stato richiesto. La funzione non restituisce infatti un valore in base al fatto che la stringa sia o meno valida, ma richiedi di reinserire la data finché questa non è corretta. Ma il programma fallisce di fare anche questo. In ogni ciclo verifichi infatti la presenza di uno solo dei tanti errori possibili in base alle date inserite in precedenza. Se quindi inserisci prima una data come "30/2/2011" e poi "30/12/2011" la data sarà segnata come invalida anche se non lo è.
3. La funzione non restituisce alcun valore anche se dovrebbe restituire un intero.
Dovresti eliminare la lettura dalla stringa dalla funzione in modo da semplificarti enormemente il programma.
Infine, la lettura da input non è valida per inserire stringhe come "30/2/1999".
Il formato corretto avrebbe dovuto essere "%d/%d/%d". Per verificare che tutti i valori siano stati inseriti dovresti memorizzarti il valore restituito da scanf e, nel caso in cui sia inferiore di 3, eliminare un'intera riga dall'input in modo da eliminare la stringa non valida dall'input e poter leggere la nuova data.
Un primo errore che è invece immediatamente visibile è l'uso di =! invece che di != nella seguente riga:
if (mm =! 2)
Immagino volessi scrivere
if (mm != 2)
Ci sono poi degli errori nel modo in cui hai scritto la funzione. In particolare:
1. La lettura della data avviene sia nel main che nella funzione data_esatta.
2. Il tuo programma non fa quello che gli è stato richiesto. La funzione non restituisce infatti un valore in base al fatto che la stringa sia o meno valida, ma richiedi di reinserire la data finché questa non è corretta. Ma il programma fallisce di fare anche questo. In ogni ciclo verifichi infatti la presenza di uno solo dei tanti errori possibili in base alle date inserite in precedenza. Se quindi inserisci prima una data come "30/2/2011" e poi "30/12/2011" la data sarà segnata come invalida anche se non lo è.
3. La funzione non restituisce alcun valore anche se dovrebbe restituire un intero.
Dovresti eliminare la lettura dalla stringa dalla funzione in modo da semplificarti enormemente il programma.
Infine, la lettura da input non è valida per inserire stringhe come "30/2/1999".
scanf("%d,%d,%d", &g, &m, &a);
Il formato corretto avrebbe dovuto essere "%d/%d/%d". Per verificare che tutti i valori siano stati inseriti dovresti memorizzarti il valore restituito da scanf e, nel caso in cui sia inferiore di 3, eliminare un'intera riga dall'input in modo da eliminare la stringa non valida dall'input e poter leggere la nuova data.
Mi sono permesso di rivedere il tuo codice....

#include <stdio.h> #include <stdlib.h> int data_esatta (int gg, int mm, int aa); main (){ int g,m,a; int data_corretta; data_corretta = data_esatta(g,m,a); printf("la data iserita e' corretta."); system ("PAUSE"); } /*funzione*/ int data_esatta (int gg, int mm, int aa){ int Err; while (1) { Err = 0; printf ("inserisci il giorno mese e l'anno: "); scanf("%d%d%d", &gg,&mm,&aa); if ((gg<=0)||(mm<=0)||(aa<=0)||(gg>31)||(mm>12)||(aa>2011)) { Err = 1; } if ((mm==11 || mm==4 || mm==6 || mm==9) && (gg>30)) { Err = 1; } if ((mm==2) && (gg >29)) { Err = 1; } if ((mm==2) && (gg >28)) { if (not((aa % 400)==0 || ((aa % 4)==0 && !((aa % 100)==0)))) { Err = 1; } } if (!Err) return 0; } }
Ciao, infatti il mio problema stava proprio nella funzione, sapevo che era scritta male richiedendo sempre la scrittura...mi ero confuso...mi spiegheresti la funzione come l'hai strutturata?
però anche in questo caso non funziona se inserisco 31/12/1990...
però anche in questo caso non funziona se inserisco 31/12/1990...
A me esegue crrettamente.
La struttura mi sembra abbastanza immediata da capire.... no ?
inserisci il giorno mese e l'anno: 31 12 1990
la data iserita e' corretta.
Process returned 0 (0x0) execution time : 3.250 s
Press any key to continue.
La struttura mi sembra abbastanza immediata da capire.... no ?
ma per caso può dipendere da che versione del C che ho? perchè a me non mi funzione ho fatto copia incolla e non va....
Salve domy90,
In che senso? Magari dipende dal tipo del complatore, quale usi?
Cordiali saluti
"domy90":
ma per caso può dipendere da che versione del C che ho? ....
In che senso? Magari dipende dal tipo del complatore, quale usi?
Cordiali saluti
@domy90: in che senso non va? Non riesci a compilarlo o il programma non funziona una volta che viene eseguito? Se non funziona quando viene eseguito potrebbe dipendere dal formato scelto per inserire la data. Nel programma di Quinzio, la data va inserita separando giorno, mese e anno da uno spazio. Inserendo al posto dello spazio (o caratteri equivalenti come la tabulazione o l'andare a capo) un carattere come / o - o , o qualsiasi altro otterresti un errore. Oppure potrebbe esserci un errore nella logica in cui vengono trovati gli errori e sarebbe in questo caso utile farci un esempio di data che viene accettata o rifiutata nonostante sia valida. In caso di errore di compilazione, scrivi il messaggio di errore del tuo compilatore e dicci quale compilatore e quali opzioni di compilazione usi.
Ho provato il codice e ci sono in effetti degli errori. In particolare la seguente condizione non è corretta in C
not non è una parola chiave del C. La versione corretta sarebbe
Inoltre le seguenti variabili non vengono utilizzate:
e neanche i corrispondenti parametri alla funzione. Come ho già detto in precedenza, input e controllo degli errori non dovrebbero essere mischiati. Prova a ignorare per ora la gestione dell'input e prova invece a scrivere data_esatta in modo da verificare se i valori passati come argomento formano una data. Scrivi poi un programma in cui usi la funzione per sapere se le seguenti date sono esatte: 29/2/1900, 29/2/1980, 29/2/2000, 33/1/1111, 2/20/1950, -3/7/1777, 31/9/1999
not((aa % 400)==0 || ((aa % 4)==0 && !((aa % 100)==0)))
not non è una parola chiave del C. La versione corretta sarebbe
!((aa % 400)==0 || ((aa % 4)==0 && !((aa % 100)==0)))
Inoltre le seguenti variabili non vengono utilizzate:
int g, m, a;
e neanche i corrispondenti parametri alla funzione. Come ho già detto in precedenza, input e controllo degli errori non dovrebbero essere mischiati. Prova a ignorare per ora la gestione dell'input e prova invece a scrivere data_esatta in modo da verificare se i valori passati come argomento formano una data. Scrivi poi un programma in cui usi la funzione per sapere se le seguenti date sono esatte: 29/2/1900, 29/2/1980, 29/2/2000, 33/1/1111, 2/20/1950, -3/7/1777, 31/9/1999
scusate se rispondo in ritardo...
dunque tipo di compilatore che uso è il DEV C++ versione 4.9.9.2.....
il programma di Quinzio non funziona una volta che viene eseguito però non dipende dal formato dell'inserimento della data infatti nella scanf ho scritto ("%d/%d/%d", &g, &m, &a);
non funziona in alcuni casi, per esempio le date:
29/2/1900, 29/2/1980, 29/2/2000, 33/1/1111, 2/20/1950, -3/7/1777, 31/9/1999 dice che sono tutte sbagliate tranne la 29/2/1980.
Invece anche 29/2/2000 deve essere inclusa tra le corrette....
dunque tipo di compilatore che uso è il DEV C++ versione 4.9.9.2.....
il programma di Quinzio non funziona una volta che viene eseguito però non dipende dal formato dell'inserimento della data infatti nella scanf ho scritto ("%d/%d/%d", &g, &m, &a);
non funziona in alcuni casi, per esempio le date:
29/2/1900, 29/2/1980, 29/2/2000, 33/1/1111, 2/20/1950, -3/7/1777, 31/9/1999 dice che sono tutte sbagliate tranne la 29/2/1980.
Invece anche 29/2/2000 deve essere inclusa tra le corrette....
Posteresti il tuo codice attuale?
si si certo... il programma è:
è sempre quello di Quinzio solo che ho corretto il not e la printf....
#include <stdio.h> #include <stdlib.h> int data_esatta (int g, int m, int a); main (){ int g,m,a; int data_corretta; printf ("inserisci il giorno mese e l'anno: "); scanf ("%d/%d/%d",&g,&m,&a); data_corretta = data_esatta(g,m,a); printf("la data iserita e' correta."); system ("PAUSE"); } /*funzione*/ int data_esatta (int gg, int mm, int aa){ int Err; while (1) { Err = 0; printf ("inserisci il giorno mese e l'anno: "); scanf("%d/%d/%d", &gg,&mm,&aa); if ((gg<=0)||(mm<=0)||(aa<=0)||(gg>31)||(mm>12)||(aa>2011)) { Err = 1; } if ((mm==11 || mm==4 || mm==6 || mm==9) && (gg>30)) { Err = 1; } if ((mm==2) && (gg >29)) { Err = 1; } if ((mm==2) && (gg >28)) { if (!((aa % 400)==0 || ((aa % 4)==0 && !((aa % 100)==0)))) { Err = 1; } } if (!Err) return 0; } }
è sempre quello di Quinzio solo che ho corretto il not e la printf....
di queste date: 29/2/1900, 29/2/1980, 29/2/2000, 33/1/1111, 2/20/1950, -3/7/1777, 31/9/1999
solo due sono corrette ovvero la: 29/2/1980 e la 29/2/2000....
il programma sopra postato, invece mi dice che solo la 29/2/1980 è corretta....
solo due sono corrette ovvero la: 29/2/1980 e la 29/2/2000....
il programma sopra postato, invece mi dice che solo la 29/2/1980 è corretta....
Prima di tutto non hai seguito le mie indicazioni riguardo al dividere meglio la gestione dell'input dal test della data. Mischiare input e output con la logica del programma è spesso una pessima idea e rende il codice più difficile da usare, leggere e modificare. Per cui il tuo main dovrebbe a mio parere apparire più o meno come segue:
Nella funzione data_esatta dovrà a questo punto apparire solo il codice per verificare che la data sia effettivamente esatta o meno.
Ma se volessi rimanere necessariamente legato al tuo design corrente, per prima cosa è inutile fare a questo punto la lettura due volte, una nel main e le altre all'interno delle funzioni. In questo modo, mancando ogni feedback sulla correttezza di una data (tranne in caso affermativo), sembra che la prima data inserita sia sempre errata, mentre non viene neanche testata. Per cui elimina le righe
dal main ed elimina anche tutti gli argomenti di data_esatta e le variabili definite nel main. Sono tutti inutilizzati. Per cui a questo punto il tuo codice, esclusa la funzione data_esatta, dovrebbe apparire più o meno come il seguente:
In questo caso la funzione data_esatta dovrà anche contenere l'input e in pratica ci si chiede a cosa serve quella funzione se in pratica contiene tutto il codice del programma.
Corretto il main in uno dei due modi (e modificata in modo opportuno la funzione data_esatta) il codice sembra funzionare sulle date da te fornite. Suppongo che il problema fosse quindi quello corretto nel capoverso precedente nel discorso sul main. Per la cronaca, la seguente è la funzione corretta usando il secondo main postato (cioè la modifica di quello da te postato).
Questo è invece la funzione modificata in modo da funzionare con il primo main (come noti si tratta in pratica del codice all'interno del ciclo).
Anche in questo caso è forse possibile rendere più leggibile il codice.
#include <stdio.h> int data_esatta(int, int, int); int main(void) { while(1) { int g, m, a; int ret; fputs("Inserire la data da verificare (gg/mm/aaaa): ", stdout); ret = scanf("%d/%d/%d", &g, &m, &a); if (ret != 3) { puts("Data inserita in modo scorretto."); while (getchar() != '\n') { } continue; } if (data_esatta(g, m, a)) { puts("La data inserita e' corretta."); break; } else { puts("Data errata."); } } return 0; }
Nella funzione data_esatta dovrà a questo punto apparire solo il codice per verificare che la data sia effettivamente esatta o meno.
Ma se volessi rimanere necessariamente legato al tuo design corrente, per prima cosa è inutile fare a questo punto la lettura due volte, una nel main e le altre all'interno delle funzioni. In questo modo, mancando ogni feedback sulla correttezza di una data (tranne in caso affermativo), sembra che la prima data inserita sia sempre errata, mentre non viene neanche testata. Per cui elimina le righe
printf ("inserisci il giorno mese e l'anno: "); scanf ("%d/%d/%d",&g,&m,&a);
dal main ed elimina anche tutti gli argomenti di data_esatta e le variabili definite nel main. Sono tutti inutilizzati. Per cui a questo punto il tuo codice, esclusa la funzione data_esatta, dovrebbe apparire più o meno come il seguente:
#include <stdio.h> void data_esatta(); int main (void) { data_esatta(); printf("la data inserita e' corretta."); return 0; }
In questo caso la funzione data_esatta dovrà anche contenere l'input e in pratica ci si chiede a cosa serve quella funzione se in pratica contiene tutto il codice del programma.
Corretto il main in uno dei due modi (e modificata in modo opportuno la funzione data_esatta) il codice sembra funzionare sulle date da te fornite. Suppongo che il problema fosse quindi quello corretto nel capoverso precedente nel discorso sul main. Per la cronaca, la seguente è la funzione corretta usando il secondo main postato (cioè la modifica di quello da te postato).
void data_esatta () { int Err; int gg, mm, aa; while (1) { Err = 0; printf ("inserisci il giorno mese e l'anno: "); scanf("%d/%d/%d", &gg,&mm,&aa); if ((gg<=0)||(mm<=0)||(aa<=0)||(gg>31)||(mm>12)||(aa>2011)) { Err = 1; } if ((mm==11 || mm==4 || mm==6 || mm==9) && (gg>30)) { Err = 1; } if ((mm==2) && (gg >29)) { Err = 1; } if ((mm==2) && (gg >28)) { if (!((aa % 400)==0 || ((aa % 4)==0 && !((aa % 100)==0)))) { Err = 1; } } if (!Err) return; } }
Questo è invece la funzione modificata in modo da funzionare con il primo main (come noti si tratta in pratica del codice all'interno del ciclo).
int data_esatta (int g, int m, int a) { if ((g<=0)||(m<=0)||(a<=0)||(g>31)||(m>12)||(a>2011)) return 0; if ((m==11 || m==4 || m==6 || m==9) && (g>30)) return 0; if ((m==2) && (g >29)) return 0; if ((m==2) && (g >28)) { if (!((a % 400)==0 || ((a % 4)==0 && !((a % 100)==0)))) return 0; } return 1; }
Anche in questo caso è forse possibile rendere più leggibile il codice.
hai ragione non ha senso la funzione che ho postato(visto che, come hai detto, contiene tutto il codice del programma)... però vorrei l'input no dalla funzione ma dal main cosicchè noi passiamo la data alla funzione che la elabora soltando, cioè se essa è corretta oppure no;
in questo modo separo anche l'input dall'elaborazione... quindi il codice è:
però adesso devo cambiare tutto, perchè nella funzione ora il while non serve più....la funzione adesso la scrivo:
il risultato della computazione dovrebbe essere ad esempio:
inserire giorno mese e l'anno nel formato gg/mm/aaaa: 1/15/1900
La data inserita e' scorretta. Riprovare
inserire giorno mese e l'anno nel formato gg/mm/aaaa: -1/12/1900
La data inserita e' scorretta. Riprovare
inserire giorno mese e l'anno nel formato gg/mm/aaaa: 1/12/1900
La data inserita è corretta.
Press any key to continue . . .
però non funziona perchè non so dove mettere il while per richiedere di inserire la data qualora non fosse corretta...
in questo modo separo anche l'input dall'elaborazione... quindi il codice è:
#include <stdio.h> #include <stdlib.h> int data_esatta (int gg, int mm, int aaaa); main (){ int g,m,a; int data_corretta; printf ("inserisci il giorno mese e l'anno nel formato gg/mm/aaaa: "); scanf ("%d/%d/%d",&g,&m,&a); data_corretta = data_esatta(g,m,a); if (data_corretta == 0) printf("la data iserita e' correta.\n"); else { printf("la data iserita e' scorreta. Riprovare\n"); } system ("PAUSE"); }
però adesso devo cambiare tutto, perchè nella funzione ora il while non serve più....la funzione adesso la scrivo:
/*funzione*/ int data_esatta (int gg, int mm, int aaaa){ int Err; Err = 0; if ((gg<=0)||(mm<=0)||(aaaa<=0)||(gg>31)||(mm>12)||(aaaa>2011)) Err = 1; else { Err = 0; } if ((mm==11 || mm==4 || mm==6 || mm==9) && (gg>30)) Err = 1; else{ Err = 0; } if ((mm==2) && (gg >29)) Err = 1; else { Err = 0; } if ((mm==2) && (gg >28)) { if (!((aaaa % 400)==0 || ((aaaa % 4)==0 && !((aaaa % 100)==0)))) Err = 1; else { Err = 0; } } return Err; }
il risultato della computazione dovrebbe essere ad esempio:
inserire giorno mese e l'anno nel formato gg/mm/aaaa: 1/15/1900
La data inserita e' scorretta. Riprovare
inserire giorno mese e l'anno nel formato gg/mm/aaaa: -1/12/1900
La data inserita e' scorretta. Riprovare
inserire giorno mese e l'anno nel formato gg/mm/aaaa: 1/12/1900
La data inserita è corretta.
Press any key to continue . . .
però non funziona perchè non so dove mettere il while per richiedere di inserire la data qualora non fosse corretta...
L'esempio di codice lo trovi nel primo main che ho postato.
ah giusto che stupido!!!! adesso lo riscrivo e non appena finito lo posto...!!!!!!!!!!!
ho finito il programma però non mi funziona dice che le date sono tutte scorrette...questo è il main:
la funzione è la stessa del post precedente.... però non capisco stavolta che errore ho fatto, in pratica il programma dovrebbe funzionare:
inserisco la data nel formato giusto;
poi l'istruzione data_corretta richiama la funzione data_esatta che fa i controlli, ammettiamo che la data inserrita è per certo corretta quindi la funzione data_esatta deve ritornare al main 0;
dunque l'istruzione if ci stampa sullo schermo: "la data iserita e' correta."
il while a questo punto termina il ciclo dato che la sua condizione non è più verificata....
però qualcosa non funziona e non so cosa....
#include <stdio.h> #include <stdlib.h> int data_esatta (int gg, int mm, int aaaa); main (){ while(1) { int g,m,a; int data_corretta; printf ("inserisci il giorno mese e l'anno nel formato gg/mm/aaaa: "); scanf ("%d/%d/%d",&g,&m,&a); data_corretta = data_esatta(g,m,a); if (data_corretta = 0) printf("la data iserita e' correta."); else { printf("la data iserita e' scorreta. Riprovare\n"); } } system ("PAUSE"); }
la funzione è la stessa del post precedente.... però non capisco stavolta che errore ho fatto, in pratica il programma dovrebbe funzionare:
inserisco la data nel formato giusto;
poi l'istruzione data_corretta richiama la funzione data_esatta che fa i controlli, ammettiamo che la data inserrita è per certo corretta quindi la funzione data_esatta deve ritornare al main 0;
dunque l'istruzione if ci stampa sullo schermo: "la data iserita e' correta."
il while a questo punto termina il ciclo dato che la sua condizione non è più verificata....
però qualcosa non funziona e non so cosa....
if (data_corretta = 0)
Dovevi metterci == 0.
si infatti pensavo che era questo il problema però se faccio così mi dice che le date sono tutte corrette e contemporaneamente mi richiede di inserire la data....*____*
Hai ragione, ma ti sei solo dimenticato di inserire una qualche istruzione come un break o un return per uscire dal ciclo o direttamente dal programma. Aggiungi una di queste operazioni nel ramo corretto dell'if e il programma dovrebbe essere finalmente corretto.