Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342

    [C]Risoluzione tema esame

    Agli abbonati di un parco divertimenti è stato assegnato un numero identificativo univoco per gestire l'accesso al parco... Gli accessi vengono memorizzati in un file che contiene righe del tipo:
    hh:mm:ss C numero

    dove hh è un numero tra [0, 23], mm tra [0, 59] e ss tra [0, 59], C è un carattere che vale "I" in caso di ingresso e "U" in caso di uscita e numero è il codice identificativo di ogni cliente.

    I dati sono memorizzati in ordine cronologico crescente.
    Il file memorizza gli accessi di un solo giorno.
    Si scriva un programma che:
    a) definisca una struttura struct accesso utile a memorizzare i dati relativi all'accesso di ciascun utente (dovrà contenere sia l'ora di ingresso che quella di uscita);
    b) definisca una funzione carica_dati che carichi i dati contenuti in un file avente la struttura descritta;
    c)definisca una funzione permanenza che riceve come argomento una struttura di tipo struct accesso e ristituisca il tempo di permanenza nel parco in secondi; questo dato può a sua volta essere memorizzato in un campo della struttura stessa;
    d)definisca una funzione media_accesso che restituisca il tempo medio di accesso calcolato su tutti gli accessi della giornata;
    e) definisca la funzione tariffa che calcoli quanto dovuto da ciascun cliente, secondo il seguente piano tariffario:
    -fino a 3 ore si paga 1€ ogni 15 minuti, arrotondando il tempo al quarto d'ora per eccesso;
    -oltre le 3 ore si paga un costo fisso aggiuntivo di 5€;
    f) si crei un file output.txt che contenga un riepilogo del tempo di accesso e del prezzo dovuto da ogni utente che è entrato nel parco, ciascuna riga abbia il formato:
    numero_utente durata tariffa
    (ordinare i dati in senso crescente di durata)

    Questo è il file accessi.txt che ho creato usando la funzione rand():

    codice HTML:
    00:05:07 I 03135
    00:24:06 U 21530
    00:55:23 I 34022
    01:00:10 I 97763
    01:07:15 U 55736
    01:13:23 U 02567
    01:35:25 U 84421
    01:38:23 U 79802
    01:54:04 U 18456
    01:58:42 I 33069
    02:13:25 I 47793
    02:13:45 I 13929
    02:14:18 U 66413
    02:16:05 U 30886
    02:23:27 I 16649
    03:23:24 I 83426
    03:25:53 U 36915
    03:36:29 I 36915
    04:02:36 U 34022
    04:26:53 U 76229
    04:33:04 I 79802
    04:45:07 I 84421
    04:52:45 U 22862
    05:02:50 U 13929
    05:29:56 I 44919
    05:34:49 I 22862
    06:34:45 I 74067
    06:47:39 U 23058
    06:55:09 I 30886
    07:04:32 U 95368
    07:20:07 I 05211
    07:27:14 I 56429
    07:37:07 U 75011
    07:42:37 I 64370
    08:10:43 I 23058
    08:12:03 U 05211
    08:21:46 U 98315
    08:54:05 U 77373
    09:20:32 U 65123
    09:51:26 I 89172
    10:02:24 U 80540
    10:16:41 U 56429
    10:20:03 U 64370
    10:36:42 I 66413
    10:38:44 I 98167
    10:43:14 U 89172
    10:52:20 I 90027
    10:53:52 U 03135
    11:03:57 I 75198
    11:14:38 I 98315
    11:22:22 U 60492
    11:24:27 U 83426
    11:40:03 U 20059
    11:45:04 U 68690
    12:13:10 U 94324
    12:13:52 I 13926
    12:39:51 U 90027
    12:41:16 I 95368
    13:02:11 U 38335
    13:02:16 I 98537
    13:23:09 I 38335
    13:33:05 I 20059
    13:38:48 U 13784
    14:27:02 U 92777
    14:32:52 U 98167
    14:42:23 U 41421
    14:45:35 U 97763
    15:16:15 I 13784
    15:30:01 U 02362
    15:38:38 U 74067
    15:44:01 U 47793
    15:49:05 I 60492
    16:21:23 U 33069
    16:43:00 I 85386
    16:47:07 I 92777
    16:55:33 U 65782
    16:57:28 U 13926
    17:04:52 I 65123
    17:13:49 I 76229
    17:14:54 I 80540
    17:26:26 I 55736
    18:04:00 U 85386
    18:04:32 I 68690
    18:13:30 I 41421
    18:21:39 I 77373
    18:31:54 U 78042
    19:15:58 U 44919
    19:23:28 I 78042
    19:42:47 I 65782
    20:18:21 I 02567
    20:26:31 I 18456
    20:43:49 I 02362
    21:01:14 U 16649
    21:22:29 U 61393
    21:32:01 I 61393
    21:35:35 I 21530
    21:39:14 I 94324
    22:05:57 U 75198
    22:16:34 I 75011
    22:35:38 U 98537
    Ora stavo cercando di fare il punto b e già mi ritrovo problemi nel procedere... questo è quello che ho scritto:


    codice:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct{
    int hh, mm, ss;
    char *C;
    int user;
    }accesso;
    
    
    
    void carica_dati(char filename[]){
    FILE *f;
    char buffer[128];
    f = fopen(filename, "r");
    if(f==NULL)    
        {
        perror("Errore apertura file");
        exit(1);    
         }
    else
        {
        int z = 0;
        while((fgets(buffer, sizeof(buffer), f))!=NULL)
            z++;     
        accesso db[z];
        int d;
        for(d=0; d<z; d++) {
        sscanf(buffer, "%d:%d:%d %s %d", &db[d].hh, &db[d].mm, &db[d].ss, db[d].C, &db[d].user); 
        
                   }    
        fclose(f);
         }
    } 
    
    
    
    
    int main(int argc, char *argv[])        
    {
        carica_dati(argv[1]);    
        
        
        
        
        
    return 0;
    }
    Non da nessun errore nella compilazione ma quando lo eseguo mi salta fuori il famoso segmentation fault

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


  2. #2
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    Ciao

    Ciao ,

    codice:
     
    z++;     
    accesso db[z];
    
    se dichiari un array di struct , non puoi cambiare dimensione , tra l'altro questo array è locale , non visibile all'esterno della funzione , quindi inutile .

    dovresti dichiarare un puntatore struct nel main ,passarlo alla funzione e allocare memoria dinamicamente con realloc() .


    altro punto , nella struct è dichiarato un puntatore al char* , che utilizzi come char , o allochi spazio per un byte "cosa insensata" o sostituisci il puntatore con un char .
    Tecnologia

  3. #3
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342
    Quote Originariamente inviata da torn24 Visualizza il messaggio
    Ciao ,

    codice:
     
    z++;     
    accesso db[z];
    
    se dichiari un array di struct , non puoi cambiare dimensione , tra l'altro questo array è locale , non visibile all'esterno della funzione , quindi inutile .

    dovresti dichiarare un puntatore struct nel main ,passarlo alla funzione e allocare memoria dinamicamente con realloc() .


    altro punto , nella struct è dichiarato un puntatore al char* , che utilizzi come char , o allochi spazio per un byte "cosa insensata" o sostituisci il puntatore con un char .
    Ciao,
    codice:
    accesso db[z]
    è fuori dal ciclo, con C se non si mettono le graffe esegue il ciclo solo sulla prima istruzione giusto? quindi perché dici che non può cambiare dimensione

    Per i puntatori e malloc mi sta venendo difficile comprenderli nonostante le guide, finisco di leggerne un'altra e vediamo se capisco quello che avevo sbagliato

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Il problema del seg fault è causato dall'uso di

    char *C;

    della struttura.

    Non puoi usare un semplice puntatore per memorizzare una stringa. Devi prima allocare lo spazio necessario.

    Per l'allocazione del vettore ti consiglio di usare la malloc.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Il problema del seg fault è causato dall'uso di

    char *C;

    della struttura.

    Non puoi usare un semplice puntatore per memorizzare una stringa. Devi prima allocare lo spazio necessario.

    Per l'allocazione del vettore ti consiglio di usare la malloc.
    Ciao, ma char C alla fine non deve andare a memorizzare un'intera stringa ma solo il carattere "C" (che vale I oppure U) quindi a che servirebbe allocare spazio se a priori conosco si tratti di un singolo carattere?
    L' sscanf non va a separare l'intera riga contenuta nel file e a prendere solo il carattere che sta tra gli spazi e %s e quindi dopo lo mette all'interno della i-esima struttura.C? (db[i])

    Scusate se magari faccio domande super-stupide

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Se deve contenere un carattere allora deve essere un char e non un puntatore. Quindi

    char C;

    e non

    char *C;

    Quindi non devi usare %s ma %c
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Se deve contenere un carattere allora deve essere un char e non un puntatore. Quindi

    char C;

    e non

    char *C;

    Quindi non devi usare %s ma %c
    Ciao, facendo come dici tu funziona, mi ero anche dimenticato dell' &:
    codice:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct{
    int hh, mm, ss;
    char C;
    int user;
    }accesso;
    
    
    
    void carica_dati(char filename[]){
    FILE *f;
    char buffer[128];
    f = fopen(filename, "r");
    if(f==NULL)    
        {
        perror("Errore apertura file");
        exit(1);    
         }
    else
        {
        int z = 0;
        while((fgets(buffer, sizeof(buffer), f))!=NULL)
            z++;     
        accesso db[z];
        int d;
        for(d=0; d<z; d++) {
        sscanf(buffer, "%d:%d:%d %c %d", &db[d].hh, &db[d].mm, &db[d].ss, &db[d].C, &db[d].user); 
    /*    printf("%d:%d:%d %c %d\n", db[d].hh, db[d].mm, db[d].ss, db[d].C, db[d].user);   */
                   }    
        fclose(f);
         }
    } 
    
    
    
    
    int main(int argc, char *argv[])        
    {
        carica_dati(argv[1]);    
        
        
        
        
        
    return 0;
    }
    Quindi ora ho la mia bella struttura caricata con i dati e dovrei cercare di suddividere gli ingressi con le uscite per poi passare alla richiesta c)
    Ho paura che mi farò risentire molto presto

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


  8. #8
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342
    A rieccome, mi avete chiamato vero?

    Ecco come ho pensato di trovare l'ingresso e uscita dell'utente e memorizzarla nella struttura:
    codice:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct{
    int hh, mm, ss;
    int hhI, mmI, ssI;
    int hhU, mmU, ssU;
    char C;
    int user;
    }accesso;
    
    
    
    void carica_dati(char filename[]){
    FILE *f;
    char buffer[128];
    f = fopen(filename, "r");
    if(f==NULL)    
        {
        perror("Errore apertura file");
        exit(1);    
         }
    else
        {
        int z = 0;
        while((fgets(buffer, sizeof(buffer), f))!=NULL)
            z++;     
        accesso db[z];
        accesso dbIU[z];
        int d, G;
        for(d=0; d<z; d++) {
        sscanf(buffer, "%d:%d:%d %c %d", &db[d].hh, &db[d].mm, &db[d].ss, &db[d].C, &db[d].user); 
        for(d=0; d<z; d++) {
        G=0;
        while(db[d].user!=db[G].user)
        G++;
        if(db[G].C=='U'){
        dbIU[d].hhI = db[d].hh;
        dbIU[d].mmI = db[d].mm;
        dbIU[d].ssI = db[d].ss;
        dbIU[d].hhU = db[G].hh;
        dbIU[d].mmU = db[G].mm;
        dbIU[d].ssU = db[G].ss;
        dbIU[d].user = db[d].user;
        }
        else
        {
        dbIU[d].hhI = db[G].hh;
        dbIU[d].mmI = db[G].mm;
        dbIU[d].ssI = db[G].ss;
        dbIU[d].hhU = db[d].hh;
        dbIU[d].mmU = db[d].mm;
        dbIU[d].ssU = db[d].ss;
        dbIU[d].user = db[d].user;
        }
        
    /*    printf("%d:%d:%d %c %d\n", db[d].hh, db[d].mm, db[d].ss, db[d].C, db[d].user);   */
                   }
        for(G=0; G<z; G++)
        printf("I%d:%d:%dU%d%d%d %d\n", dbIU[G].hhI, dbIU[G].mmI, dbIU[G].ssI, dbIU[G].hhU, dbIU[G].mmU, dbIU[G].ssU, dbIU[G].user); 
        
            
        fclose(f);
         }
       } 
    }
    
    
    
    int main(int argc, char *argv[])        
    {
        carica_dati(argv[1]);    
        
        
        
        
        
    return 0;
    }
    A quanto pare alla compilazione il computer non è esploso e non mi ha dato errori, però eseguendolo la printf spara roba assurda non passerò mai questo esame

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


  9. #9
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    Ciao

    Ciao , invece di aiutarti , perchè ci sono persone competenti che possono farlo in maniera ottimale , vorrei chiederti io di aiutarmi a capire il tuo codice .

    Vorrei sapere cosa fa questo spezzone di codice ???

    codice:
    int z =0;
        while((fgets(buffer,sizeof(buffer), f))!=NULL)
            z++;     // QUI CONTI LE RIGHE DEL FILE , MA BUFFER COSA CONTIENE A FINE CICLO  ?????
        accesso db[z];
        int d;
        for(d=0; d<z; d++){// QUI ESEGUI SSCANF PER IL NUMERO DI RIGHE FILE , MA BUFFER NON E' LA STESSA STRINGA ??????
        sscanf(buffer,"%d:%d:%d %s %d",&db[d].hh,&db[d].mm,&db[d].ss, db[d].C,&db[d].user); 
        
    Ultima modifica di torn24; 11-07-2014 a 08:03
    Tecnologia

  10. #10
    Utente di HTML.it L'avatar di fedrock
    Registrato dal
    Jun 2009
    residenza
    Milan
    Messaggi
    342
    Quote Originariamente inviata da torn24 Visualizza il messaggio
    Ciao , invece di aiutarti , perchè ci sono persone competenti che possono farlo in maniera ottimale , vorrei chiederti io di aiutarmi a capire il tuo codice .

    Vorrei sapere cosa fa questo spezzone di codice ???

    codice:
    int z =0;
        while((fgets(buffer,sizeof(buffer), f))!=NULL) 
            z++;     // QUI CONTI LE RIGHE DEL FILE , MA BUFFER COSA CONTIENE A FINE CICLO  ?????
        accesso db[z];
        int d;
        for(d=0; d<z; d++){// QUI ESEGUI SSCANF PER IL NUMERO DI RIGHE FILE , MA BUFFER NON E' LA STESSA STRINGA ??????
        sscanf(buffer,"%d:%d:%d %s %d",&db[d].hh,&db[d].mm,&db[d].ss, db[d].C,&db[d].user); 
        
    Caspita hai ragione, li c'è un errore logico non me ne ero accorto
    Mi serviva il numero delle righe per stabile la dimensione dell'array di strutture accesso ecco perché tutto quel casino...
    Quindi il codice giusto dovrebbe essere;
    codice:
    int z =0;
        while((fgets(buffer,sizeof(buffer), f))!=NULL) {
            z++;
    }
        accesso db[z];
       while((fgets(buffer,sizeof(buffer), f))!=NULL) {
        sscanf(buffer,"%d:%d:%d %s %d",&db[d].hh,&db[d].mm,&db[d].ss, db[d].C,&db[d].user);
    }
    C'è comunque qualcosa che non mi convinge... Non ho usato puntatori (perché non li so usare bene) però mi ricordo che all'esame molti l'hanno fatto con i puntatori (quelli che l'hanno passato)

    I SHOULD TELL YOU SOMETHING NEW:
    don't want you here.


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.