[C] gestione accessi ad un sito web
ciao
sto cercando di risolvere un tema d'esame che mi richiede:
Dato un .txt che contiene su ogni riga giorno dell'anno(intero da 1 a 365), ora di accesso(intero da 1 a 24), durata di login in minuti(intero), si trovi dopo aver letto il file:
1)il numero e la durata tot degli accessi nel primo semestre..
2)il numero e la durata tot degli accessi mese x mese..(anno non bisestile), creando un report che contiene,numero_mese(1-12), numero_accessi x mese,durata di navigazione x mese....
Ho voluto usare un approccio x strutture...Per il primo punto nessun problema..Per il secondo la divisione dei mesi e i relativi calcoli non riesco ad impostarli...Qualcuno ha qualche consiglio sul come poter scrivere?
Ecco il codice che ho scritto finora:

sto cercando di risolvere un tema d'esame che mi richiede:
Dato un .txt che contiene su ogni riga giorno dell'anno(intero da 1 a 365), ora di accesso(intero da 1 a 24), durata di login in minuti(intero), si trovi dopo aver letto il file:
1)il numero e la durata tot degli accessi nel primo semestre..
2)il numero e la durata tot degli accessi mese x mese..(anno non bisestile), creando un report che contiene,numero_mese(1-12), numero_accessi x mese,durata di navigazione x mese....
Ho voluto usare un approccio x strutture...Per il primo punto nessun problema..Per il secondo la divisione dei mesi e i relativi calcoli non riesco ad impostarli...Qualcuno ha qualche consiglio sul come poter scrivere?
Ecco il codice che ho scritto finora:
#include <stdio.h> #include <stdlib.h> #define MASS 499 #define MESI 12 #define GG 365 struct accessi{ int giorno; int ora; int tempo; }; struct report{ int mese; int accessi; int durata; }; struct accessi accesso[MASS]; struct report x_mese[MESI]; int n_accessi(); int durata_sem(); void analisi_mese(); int main(void) { int i=0,count=0,durata=0,mese=0,m=0,giorno; FILE *fp; fp=fopen("accessi.txt","r"); for(i=0;i<MASS;i++){ fscanf(fp,"%d %d %d",&accesso[i].giorno,&accesso[i].ora,&accesso[i].tempo); } fclose(fp); giorno=accesso[i].giorno ; count=n_accessi(); durata=durata_sem(); printf("Nel primo semestre si sono verificati %d accessi per una durata complessiva di %d minuti.\n",count,durata); analisi_mese(); } int n_accessi() { int gg_sem=GG/2,i=0,count=0; for(i=0;accesso[i].giorno<gg_sem;i++){ count++; } return count; } int durata_sem() { int i,durata=0; for(i=0;accesso[i].giorno<GG/2;i++){ durata+=accesso[i].tempo; } return durata; } void analisi_mese() { int i=0; int mese[12]={1,2,3,4,5,6,7,8,9,10,11,12}; for(i=0;i<MASS;i++){ if(accesso[i].giorno<=31 ) { x_mese.mese[i]=1; count[i]++; durata[i]+=accesso[i].tempo; } else if(accesso[i].giorno<=59) { x_mese.mese[i]=2; count[i]++; durata[i]+=accesso[i].tempo; } else if(accesso[i].giorno<=90) { x_mese.mese[i]=3; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=120) { x_mese.mese[i]=4; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=151) { x_mese.mese[i]=5; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=181) { x_mese.mese[i]=6; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=212) { x_mese.mese[i]=7; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=243) { x_mese.mese[i]=8; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=273) { x_mese.mese[i]=9; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=303) { x_mese.mese[i]=10; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=334) { x_mese.mese[i]=11; count[i]++; durata[i]+=accesso[i].tempo; }else { x_mese.mese[i]=12; count[i]++; durata[i]+=accesso[i].tempo; } } }
Risposte
Il metodo più semplice per gestire i mesi è quello di crearti un array statico (il calendario non cambia
) in cui inserisci il mese di ogni giorno dell'anno e poi gestisci altri array che contengono, per ogni mese questa volta, il numero di accessi e la durata di navigazione mensile.

mmm non credo di aver capito bene...ho provato in questa maniera ma ho un bell'errore di segmentazione
L'errore lo ottengo cercando di stampare il numero di accessi per mese...


#include <stdio.h> #include <stdlib.h> #define MASS 499 #define MESI 12 #define GG 365 struct accessi{ int giorno; int ora; int tempo; }; struct report{ int mese; int accessi; int durata; }; struct accessi accesso[MASS]; struct report x_mese[MESI]; int n_accessi(); int durata_sem(); void analisi_mese(); int main(void) { int i=0,count=0,durata=0,mese=0,m=0,giorno; FILE *fp; fp=fopen("accessi.txt","r"); for(i=0;i<MASS;i++){ fscanf(fp,"%d %d %d",&accesso[i].giorno,&accesso[i].ora,&accesso[i].tempo); } fclose(fp); giorno=accesso[i].giorno ; count=n_accessi(); durata=durata_sem(); printf("Nel primo semestre si sono verificati %d accessi per una durata complessiva di %d minuti.\n",count,durata); analisi_mese(); } int n_accessi() { int gg_sem=GG/2,i=0,count=0; for(i=0;accesso[i].giorno<gg_sem;i++){ count++; } return count; } int durata_sem() { int i,durata=0; for(i=0;accesso[i].giorno<GG/2;i++){ durata+=accesso[i].tempo; } return durata; } void analisi_mese() { int i=0,count[12],durata[12]; int mese[12]={1,2,3,4,5,6,7,8,9,10,11,12}; for(i=0;i<MASS;i++){ if(accesso[i].giorno<=31 ) { x_mese[i].mese=1; count[i]++; durata[i]+=accesso[i].tempo; } else if(accesso[i].giorno<=59) { x_mese[i].mese=2; count[i]++; durata[i]+=accesso[i].tempo; } else if(accesso[i].giorno<=90) { x_mese[i].mese=3; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=120) { x_mese[i].mese=4; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=151) { x_mese[i].mese=5; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=181) { x_mese[i].mese=6; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=212) { x_mese[i].mese=7; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=243) { x_mese[i].mese=8; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=273) { x_mese[i].mese=9; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=303) { x_mese[i].mese=10; count[i]++; durata[i]+=accesso[i].tempo; }else if(accesso[i].giorno<=334) { x_mese[i].mese=11; count[i]++; durata[i]+=accesso[i].tempo; }else { x_mese[i].mese=12; count[i]++; durata[i]+=accesso[i].tempo; } } for(i=0;i<12;i++){ printf("%d\n",count[i]); } }
L'errore lo ottengo cercando di stampare il numero di accessi per mese...
count è un intero, non puoi indicizzarlo come se fosse un array...
[size=150]EDIT: NO SCUSA HO DETTO UNA BAGGIANATA!
[/size]
[size=150]EDIT: NO SCUSA HO DETTO UNA BAGGIANATA!

@Dante.utopia:
tranquillo! 
non riesco a risolvere quell'errore di segmentazione..


non riesco a risolvere quell'errore di segmentazione..

Comunquesia, gli errori si seg. sono spesso dovuti alla scrittura fuori dal range dei vettori, ti consiglio di controllare bene gli indici.
Per prima cosa potresti far notare al professore che se l'ora di accesso va da 1 a 24 invece che da 0 a 23 allora se io mi connetto a mezzanotte allora mi conta le ore nel giorno precedente
. Dovresti inoltre, immagino, misurare quando la connessione passa al giorno successivo.
Come seconda cosa vorrei informarti che le strutture non sono un approccio, ma uno strumento. Veniamo ora al perché il tuo approccio è discutibile. Devo supporre che il report vada scritto su file o schermo?
Il primo aspetto importante da segnalare è che il singolo accesso partecipa al conto solo per aumentare il numero e la durata degli accessi per mese. E che un semestre è la somma dei primi sei mesi. Quindi in sostanza l'unica cosa che va memorizzata è il report mese x mese. Userai quindi variabili temporanee per aggiornare il report e userai questo report per calcolarti la variabile semestrale.
Il secondo aspetto importante, relativamente alle strutture, è che se tu memorizzi il report in un array di strutture allora il mese è rappresentato dall'indice (seppur ridotto di 1) e non vi è ragione per memorizzarlo due volte. Inoltre la struttura report può essere utilizzata anche per memorizzare il dato semestrale (se la variabile mese viene eliminata).
Come detto inoltre non vi è alcuna ragione per la struttura accessi. Vorrei inoltre evidenziare che non serve creare variabili globali e che ha poco senso memorizzare 12 e 365 come #define[nota]L'uso dei define ha lo scopo di settare variabili di ambiente che potrebbero essere soggetti a modifiche future. Per esempio MASS ha senso. Ma nel caso di mesi e giorni, scrivere MESI al posto di 12 non ha alcun senso (tutti sanno che ci sono 12 mesi e scrivere MESI al suo posto non rende il codice più leggibile).[/nota].
Come ha fatto notare apatriarca potrebbe essere comodo usare una look-up-table per determinare il mese collegato al giorno. Di fatto costruisci un array static e lo inizializzi la prima volta che accedi alla funzione (devi assicurarti di non riinizializzarlo più di una volta)[nota]Puoi anche inserire direttamente l'array di 365 elementi con i valori inseriti a mano ma direi che è noioso.08[/nota].

Come seconda cosa vorrei informarti che le strutture non sono un approccio, ma uno strumento. Veniamo ora al perché il tuo approccio è discutibile. Devo supporre che il report vada scritto su file o schermo?
Il primo aspetto importante da segnalare è che il singolo accesso partecipa al conto solo per aumentare il numero e la durata degli accessi per mese. E che un semestre è la somma dei primi sei mesi. Quindi in sostanza l'unica cosa che va memorizzata è il report mese x mese. Userai quindi variabili temporanee per aggiornare il report e userai questo report per calcolarti la variabile semestrale.
Il secondo aspetto importante, relativamente alle strutture, è che se tu memorizzi il report in un array di strutture allora il mese è rappresentato dall'indice (seppur ridotto di 1) e non vi è ragione per memorizzarlo due volte. Inoltre la struttura report può essere utilizzata anche per memorizzare il dato semestrale (se la variabile mese viene eliminata).
Come detto inoltre non vi è alcuna ragione per la struttura accessi. Vorrei inoltre evidenziare che non serve creare variabili globali e che ha poco senso memorizzare 12 e 365 come #define[nota]L'uso dei define ha lo scopo di settare variabili di ambiente che potrebbero essere soggetti a modifiche future. Per esempio MASS ha senso. Ma nel caso di mesi e giorni, scrivere MESI al posto di 12 non ha alcun senso (tutti sanno che ci sono 12 mesi e scrivere MESI al suo posto non rende il codice più leggibile).[/nota].
Come ha fatto notare apatriarca potrebbe essere comodo usare una look-up-table per determinare il mese collegato al giorno. Di fatto costruisci un array static e lo inizializzi la prima volta che accedi alla funzione (devi assicurarti di non riinizializzarlo più di una volta)[nota]Puoi anche inserire direttamente l'array di 365 elementi con i valori inseriti a mano ma direi che è noioso.08[/nota].
Comunque non stai controllando di essere arrivato a fine file prima di leggere i 499 accessi e io non vedo nel testo che gli accessi sono 499.