C : chiediamo consigli agli esperti ;)

10 risposte [Ultimo messaggio]
Ritratto di anubis
User offline. Last seen 2 ore 9 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno

Visto che il codice di per se funziona, forse questo topic è inutile, ma sarei veramente curioso di sapere cosa ne pensate:

#include 

#include 

#define SIZE 2

#define LUNGHEZZA 20</p>
<p>typedef struct {

    int giorno;

    int mese;

    int anno;

} data;</p>
<p>typedef struct {

    char nome[LUNGHEZZA];

    char cognome[LUNGHEZZA];

    data nascita;

    int matricola;

} studente;</p>
<p>int importData (data *);

void importStudente (studente *m);</p>
<p>int main () {</p>
<p>    studente classe[SIZE];

    int i;</p>
<p>    //inizializzo array classe

    for (i=0; i

    strcpy(classe.nome,".");

    strcpy(classe.cognome,".");

    classe[i].nascita.giorno=0;

    classe[i].nascita.mese=0;

    classe[i].nascita.anno=0;

    classe[i].matricola=0;

    }</p>
<p>    for (i=0; i
    importStudente(&classe[i]);

    }</p>
<p>    for (i=0; i[/i][/i][/i][/i][/i]
[i][i][i][i][/i][/i][/i][/i]

[i][i][i][i][i]    printf("Nome: %s", classe[i].nome);<br />
    printf("Cognome: %s", classe[i].cognome);<br />
    printf("Data di Nascita: %d/%d/%d\n", classe[i].nascita.giorno, classe[i].nascita.mese, classe[i].nascita.anno);<br />
    printf("Matricola: %d\n", classe[i].matricola);<br />
    printf("\n");<br />
    }</p>
<p>    return 0;<br />
}</p>
<p>void importStudente (studente *mystudente) {</p>
<p>    printf("Digitare il Nome dello Studente:\n");<br />
    fgets(mystudente->nome, LUNGHEZZA, stdin);</p>
<p>    printf("Digitare il Cognome dello Studente:\n");<br />
    fgets(mystudente->cognome, LUNGHEZZA, stdin);</p>
<p>    printf("Digitare la data di nascita dello Studente:\n");<br />
    while (importData (&mystudente->nascita) == 1) {<br />
    }</p>
<p>    printf("Digitare il Numero di Matricola dello Studente:\n");<br />
    scanf("\n%d", &mystudente->matricola);</p>
<p>    /* Devo intercettare "\n" o con un utilizzo ricorsivo<br />
     * di questa funzione, andrebbe a terminare l'fgets<br />
     * per aquisire il nome.<br />
     */</p>
<p>    while( getchar()!='\n');</p>
<p>}</p>
<p>//La funziona ritorna 0 se la data è valida, 1 altrimenti</p>
<p>int importData (data *mydata) {</p>
<p>    data controllo = {0,0,0};</p>
<p>    printf("Digitare la data nel formato gg/mm/aaaa: ");<br />
    scanf("%d/%d/%d", &controllo.giorno, &controllo.mese, &controllo.anno);</p>
<p>    if ( (0 > controllo.mese) || (controllo.mese > 12) ) {<br />
        printf("Data non valida, il mese non e' corretto\n");<br />
        return 1;<br />
    }<br />
    else {<br />
        switch (controllo.mese) {<br />
            case 1:<br />
            case 3:<br />
            case 5:<br />
            case 7:<br />
            case 8:<br />
            case 10:<br />
            case 12:<br />
                if ( (0 > controllo.giorno) || (controllo.giorno > 31) ) {<br />
                    printf("Data non valida, il giorno non e' corretto\n");<br />
                    return 1;<br />
                }<br />
                break;<br />
            case 4:<br />
            case 6:<br />
            case 9:<br />
            case 11:<br />
                if ( (0 > controllo.giorno) || (controllo.giorno > 30) ) {<br />
                    printf("Data non valida, il giorno non e' corretto\n");<br />
                    return 1;<br />
                }<br />
                break;<br />
            case 2:<br />
                if( ( ( (controllo.anno%4) == 0) && (controllo.anno%100 !=0) ) || (controllo.anno%400 == 0)) {<br />
                        if ( (0 > controllo.giorno) || (controllo.giorno > 29) ) {<br />
                            printf("Data non valida, il giorno non e' corretto\n");<br />
                            return 1;<br />
                        }<br />
                }</p>
<p>                else {<br />
                        if ( (0 > controllo.giorno) || (controllo.giorno > 28) ) {<br />
                            printf("Data non valida, il giorno non e' corretto\n");<br />
                                if (controllo.giorno == 29)<br />
                                printf("L'anno %d NON e' bisestile\n", controllo.anno);<br />
                            return 1;<br />
                        }<br />
                }<br />
                 break;<br />
            default:<br />
                break;<br />
        }</p>
<p>    }</p>
<p>    mydata->giorno = controllo.giorno;<br />
    mydata->mese   = controllo.mese;<br />
    mydata->anno   = controllo.anno;</p>
<p>    return 0;<br />
}<br />
[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
  [i][i][i][i][i][i][i][i][i][i][i] 

eventuali modifiche, miglioramenti, critiche??

Il prossimo passo sarà quello di stampare i dati relativi agli studenti non più studente per studente, ma in una tabella (nome, cognome, data nascita, matricola) con gli elementi ordinati alfabeticamente (per nome e cognome) o per anno (dal più vecchio al più giovane) o in ordine crescente (per le matricole), in base alle richieste dell'utente...[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

Ritratto di anubis
User offline. Last seen 2 ore 9 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

c'è qualcosa che non va... non gli piace il codice :P
eccolo qui:
http://pastebin.com/m2401caf1

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

User offline. Last seen 5 giorni 2 ore ago. Sconnesso
Iscritto: 03/10/2005
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Ciao

L'unica critica di fondo che si può fare al tuo programma riguarda l'uso della struttura data.
L'uso di una struttura del genere rende un incubo qualsiasi operazione statistica (anche il solo semplice sort) su tale campo.

Da che programmazione è programmazione i campi data / ora vengono salvate sempre in un unico campo numerico con lo 0 fisso ad una determinata data (se non ricordo male 1/1/1970) questo per rendere semplicissime le operazioni sulle date (specialmente le comparazioni).

Se vuoi evitare la conversione della data puoi usare una stringa nel formato AAAAMMGG o un long int con Anno*10000 + Mese*100 + Giorno

Ciao Ciao, Moreno

User offline. Last seen 2 settimane 5 giorni ago. Sconnesso
Iscritto: 12/12/2006
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Moreno ha ragione. In C soprattutto è impensabile fare un ordinamento su delle strutture allocate staticamente (costa tempo e memoria). Io fossi in te, prima di completare questo progettino,andrei un altro pochino avanti nello studio. Di solito per questo genere di operazioni si usa l'allocazione dinamica della memoria (attraverso i puntatori) e una struttura dati che si presti bene al tipo di operazioni da fare (ad esempio una lista, se ordinata potrebbe ridurre ulteriormente il numero di calcoli, magari per operazioni che vengono effettuate con una certa frequenza).
Senza dimenticare che faciliterebbero non poco l'implementazioni di qualsiasi algoritmo di ricerca/ordinamento.

Ritratto di anubis
User offline. Last seen 2 ore 9 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

l'aritmetica dei puntatori l'ho finita questa mattina, ma forse sono tonto, non vedo come potrei trovarne vantaggio qui.
@ moreno.
ho cercato qualcosa che mi facesse vedere come gestire le date come suggerito ma ho trovato solo questo:
http://thedevelopers.netsons.org/c-funzione-di-gestione-data/  (questo controllo sulla data è anche più sofisticato del mio :) )
qui invece ho trovato praticamente la stessa struttura che ho fatto:
http://www.mrwebmaster.it/cplusplus/guide/gestione-date_290.html 

potresti farmi un esempio? Ad onor di cronaca sono interessato per mio sapere personale, dato che l'esercizio chiedeva espressamente di usare quel tipo di struttura!

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

User offline. Last seen 2 settimane 5 giorni ago. Sconnesso
Iscritto: 12/12/2006
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Io parlavo di aritmetica dei puntatori nell'altro topic, comunque pensavo ti sarebbe tornata utile nel caso tu avessi voluto definire la dimensione dell'array a run time. Ad esempio:

<br />
studente *s;<br />
int num_studenti;<br />
printf("Inserire numero studenti: ");<br />
scanf("%d",&num_studenti);<br />
s = (studente*) malloc(num_studenti*sizeof(studente)); 
   
In alcuni codici puoi trovare anche il malloc senza niente davanti, perchè avviene un casting implicito, comunque per avere la certezza assoluta che tutto funzioni metterlo non è certo di troppo, anzi. A questo punto per accedere ai vari studenti ti basterebbe usare l'aritmetica dei  puntatori:
<br />
for(i=0;i<br />
       (s+i)->nome=....<br />
   

PS: sto abbozzando questo codice così su due piedi, potrebbe esserci qualche errore sintattico, ma la logica è giusta. Se hai qualche roblema posta pure.

User offline. Last seen 5 giorni 2 ore ago. Sconnesso
Iscritto: 03/10/2005
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Ciao

Non mi stavo riferendo alle routines di input ed analisi della data ma proprio alla variabile di memorizzazione della stessa.

Invece della struttura data sarebbe meglio usare una variabile data di tipo time_t definito in time.h

#ifndef _TIME_T
#define _TIME_T
typedef long time_t;
#endif

ed usare le routines mktime e localtime per operare sulla variabile (per maggiori info http://www.cplusplus.com/reference/clibrary/ctime/ )

Se vuoi ad esempio ordinare i tuoi allievi in ordine di data di nascita con la tua struttura ti spari mentre con variabili time_t è una baggianata data che a numero maggiore corrisponde data maggiore.

User offline. Last seen 9 ore 57 min ago. Sconnesso
Iscritto: 21/09/2007
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Oltre ai consigli precedenti, ne aggiungo uno di stile:
se hai:

<br />
...<br />
if ( ... ) {<br />
     ...<br />
     return 1<br />
}<br />
else {<br />
     ...<br />
     return 2<br />
}<br />
 

puoi sempre semplificare il codice con:

<br />
...<br />
if ( ... ) {<br />
     ...<br />
     return 1<br />
}<br />
...<br />
return 2<br />

User offline. Last seen 18 settimane 20 ore ago. Sconnesso
Iscritto: 01/10/2004
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Quote: l'aritmetica dei puntatori l'ho finita questa mattina, ma forse sono tonto, non vedo come potrei trovarne vantaggio qui.
@ moreno.
ho cercato qualcosa che mi facesse vedere come gestire le date come suggerito ma ho trovato solo questo:
http://thedevelopers.netsons.org/c-funzione-di-gestione-data/  (questo controllo sulla data è anche più sofisticato del mio :) )
qui invece ho trovato praticamente la stessa struttura che ho fatto:
http://www.mrwebmaster.it/cplusplus/guide/gestione-date_290.html 

potresti farmi un esempio? Ad onor di cronaca sono interessato per mio sapere personale, dato che l'esercizio chiedeva espressamente di usare quel tipo di struttura! 
Se è richiesto l'uso di una struttura, semplicemente ignora i commenti precedenti, che fanno riferimento a convenzioni che, eventualmente, potrai imparare più avanti. Ora pensa ad imparare il C :-)
Quanto all'uso dell'allocazione dinamica in C, aspetta ad usarla quando te la spiegheranno. E in ogni caso è un'esperienza dolorosa a confronto con altri linguaggi.
Quanto ad ordinare per data, con la struttura non ottieni il massimo dell'efficienza, ma non è un'operazione così complicata. Devi semplicemente usare un algoritmo di ordinamento tre volte, in sequenza:
- Ordina per anno
- Ordina per mese
- Ordina per giorno
Ciao

User offline. Last seen 18 settimane 20 ore ago. Sconnesso
Iscritto: 01/10/2004
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Quote: Oltre ai consigli precedenti, ne aggiungo uno di stile:
se hai:

<br />
...<br />
if ( ... ) {<br />
     ...<br />
     return 1<br />
}<br />
else {<br />
     ...<br />
     return 2<br />
}<br />
 

puoi sempre semplificare il codice con:

<br />
...<br />
if ( ... ) {<br />
     ...<br />
     return 1<br />
}<br />
...<br />
return 2<br />
   
 Vero, ma non mi piace a livello di leggibilità. Preferisco la prima versione e un return di default per evitare un warning

User offline. Last seen 9 ore 57 min ago. Sconnesso
Iscritto: 21/09/2007
Punti : 0
Gruppi: Nessuno
Re: C : chiediamo consigli agli esperti ;)

Non da warning ("gcc -Wall -ansi ...").
Era solo per accorciare il codice dove possibile.

Condividi contenuti