[ C ] Passare liste/record/strutture ad un file e stamparle

Pubblicità

Trigun86

Utente Attivo
Messaggi
24
Reazioni
0
Punteggio
25
Come da titolo dovrei fare un esercizio in c creare un struttura, memorizzarla in un file...per poi fare una ricerca successivamente all'interno del file e stampare a video la lista trovata...
per ora ho creato la lista ma non so come memorizzarla in un file.
Codice:
typedef struct studente *riferimento;

typedef struct{
        int matricola;
        char cognome[10];
        char nome[10];
        riferimento next;
        }studente;
        
void prompt(void);
studente *crea_lista(void);
void update(studente *);


int num_record;


int main(){
    studente *first;
    prompt();
    first=crea_lista();
    update(first);
    stampa(first);
    
    system("pause");
    return 0;
}


void prompt(void){
     
     printf("Quanti studenti vuoi inserire?\n");
     scanf("%d",&num_record);
     }
     
studente *crea_lista(){
        studente *head;
        if(num_record==0)
        return NULL;
        else{
        --num_record;
        head = malloc(sizeof(studente));
        head->next=crea_lista();
        return head;
        }
}
void update(studente *uno){
     printf("Funzione Update\n");
     int cont=1;
     while(uno!=NULL){
                      printf("Inserisci la matricola dello studente %d \n",cont);
                      scanf("%d",&uno->matricola);
                      printf("Inserisci il cognome dello studente \n");
                      scanf("%s",uno->cognome);
                      printf("Inserisci il nome dello studente \n");
                      scanf("%s",uno->nome);
                      uno=uno->next;
                      cont=cont+1;
                      printf("\n\n");
                      }
}
fatto questo come inserisco tutto in un file??? e come faccio la ricerca in modo tale che ricercando la matricola 0001 me ne stampi nome e cognome a video??? grazie per l'aiuto
 
Ciao,

da quello che vedo sembra un esercizio a scopo "didattico" quindi ti indicherò un approccio non particolarmente sofisticato.

Puoi considerare le istanze della tua struttura come "elementi atomici", ciò significa che nell'interfacciarti col file non ragioni in termini di nome, cognome ecc ma unicamente in termini di struttura nella sua interezza.

Dovrai quindi avere una funzione che inserisce un'istanza (sottoforma di stringa) nel file ed una che estrae un'istanza da file. Fatto questo basta ciclare per estrarre n istanze o inserire n istanze.

In questo modo il problema si traduce sostanzialmente in manipolazione di stringhe.

In particolare ti servirà una funzione che data un'istanza della struttura ti restituisca una stringa codificata opportunamente. Ad esempio dato in ingresso lo studente Marco Pipparello 014456 ti restituisce la stringa: "$Marco$Pipparello$014456".
Per inserire l'instanza nel file ti basta fare una fwrite della stringa. Ti conviene usare un carattere speciale per separare le varie istanze, ad esempio #.

Per esempio, dopo 3 inserimenti, il file sarà del tipo:

$Marco$Pipparello$014456
#
$Luca$Ciccetto$014452
#
$Giacomo$Panzone$014443
#

Per cercare nel file ti sposti in base agli # e tramite fread estrai tutta la stringa relativa a una istanza.
Poi ti occorre una funzione che data una stringa opportunamente codificata (es. "$Marco$Pipparello ì$014456") ti restituisca la struttura relativa.
Ti basta quindi estrarre una stringa con fread, applicare la funzione, valutare se i membri della struttura soddisfano il criterio e salvarteli ad esempio in una lista. Ciclando puoi esaminare tutto il file.

E' evidente che si possono utilizzare soluzioni migliori e più efficienti... questo sistema però è semplice in quanto si riconduce a realizzare due funzioni di conversione struct->stringa e stringa->struct.

Se volessi soluzioni migliori piuttosto userei DB.

Ciau!
 
Ciao,

da quello che vedo sembra un esercizio a scopo "didattico" quindi ti indicherò un approccio non particolarmente sofisticato.....

.....Se volessi soluzioni migliori piuttosto userei DB.

Ciau!

grazie per la tua esaustiva risposta,inserendo caratteri di escape all'interno delle stringhe è una buona soluzione ma volendo scrivere o far scrivere all'utente qualcosa di piu "pulito" senza usare db come potrei fare???

non è che per caso hai qualche codice da mostrarmi come esempio???
grazie :)
 
Potresti provare le funzioni fwrite(), fread() e fseek()... in questo modo puoi scrivere e leggere sul file l' intera struttura senza separatori o altro, visto che la dimensione dei record è fissa.
Inoltre, con fseek() puoi salvare la posizione del file dove è stato scritto un particolare contatto, così per le ricerche successive sai già dove trovarlo
 
Ciao,

volendo scrivere o far scrivere all'utente qualcosa di piu "pulito" senza usare db come potrei fare???

devi distinguere tra
1) volendo scrivere qualcosa di più pulito (su file) e
2) far scrivere all'utente qualcosa di piu pulito

per il punto 2 col metodo che ti ho descritto non ci sono problemi in quanto l'utente deve esclusivamente inserire i dati di interesse (nome, cognome, matricola) esattamente come fai adesso con scanf riempiendo la struttura.
Non deve inserire "$Marco$Pipparello$014456", sarà la tua funzione, data la struttura, a farlo (banalmente concatenando le stringhe della struttura precedute da $).

per il punto 1 puoi organizzare la struttura del file come preferisci, i caratteri speciali facilitano la ricerca rendendola relativamente "sicura" senza sforzi aggiuntivi.
Ad esempio come separatori potresti usare gli spazi e gli "a capo" ma è più rischioso perchè l'utente potrebbe (ragionevolmente) includerli durante l'insermento e ciò porterebbe il tuo file in uno stato non consistente. Dovresti quindi implementarti un piccolo parser delle stringhe inserite dall'utente.
Comunque in quanto a leggibilità, consistenza, flessibilità e semplicità realizzativa il metodo che ti ho indicato mi sembra un buon compromesso.
Volendo potresti anche usare XML...


Potresti provare le funzioni fwrite(), fread() e fseek()... in questo modo puoi scrivere e leggere sul file l' intera struttura senza separatori o altro, visto che la dimensione dei record è fissa.

il metodo che gli ho consigliato prevede proprio l'uso di fwrite(), fread() e fseek() per scrivere e leggere su file l'intera struttura in modo "atomico" però utilizza dei separatori.
E' vero che , ora, i record hanno dimensione fissa e potrebbe usare il numero di "char" o di "byte" per leggere e scrivere da file, ma se un domani decidesse di usare strutture dinamiche (ragionevolmente) per contenere le stringhe della struttura dovrebbe cambiare completamente approccio.
Inoltre potrebbe decidere che char[10] non è più sufficiente perchè sono arrivati studenti brasiliani del tipo "Luis Nazario Pepitinho da Silva" e dovrebbe cambiare dimensione al record. I vecchi file salvati non sarebbero più consistenti.


P.S
ti consiglio di codificare la matricola direttamente come stringa e non di convertirla dopo...
oltre al fatto che potrebbe contenere caratteri, potrebbe esistere una matricola che inizia con uno o più 0 che ha senso per una stringa ma non per un intero.

Ciao!
 
Dopo svariati tentativi sono riuscito a scrivere qualcosa seguendo i vostri consigli :
Codice:
#include <stdio.h>#include <ctype.h>
#include<stdlib.h>
#define DIM 2


typedef struct { 
        char nome[15];
        char cognome[15];
        char via[10];
        int eta;
} Persona;


Persona P[DIM];


int main(){ 
    int crea_vettore(Persona V[], int dim);
    int  n;
    FILE *file;
    char nome[30];
    printf("Inserisci il nome del file: ");
    gets(nome); 
    n=crea_vettore(P,DIM);


    if ((file=fopen(nome, "wb"))==NULL){ 
                          printf("Impossibile aprire file%s\n", nome);
                          return 1;
    }


    fwrite(P,sizeof(Persona),n,file);
    fclose(file);


    system("PAUSE");
    return 0;
    }


int crea_vettore(Persona P[], int dim){ 
    int i=0;
    char s[80];
    printf("funzione crea_vettore\n");
    while (!feof(stdin) && i<dim){
          printf("Inserisci nome cognome via ed eta'\n"); 
          scanf("%s\n",&P[i].nome);
          scanf("%s\n",&P[i].cognome);
          scanf("%s\n",&P[i].via);
          scanf("%d",&P[i].eta);
          gets(s);
          i++;
          printf("%d\n",i);
          printf("%s\n%s\n%s\n%d\n",P[i].nome,P[i].cognome,P[i].via,P[i].eta);
    }
    return i;
    }
il programma completa l'esecuzione ma al momento della stampa mi da dei valori numerici sballati senza stampare il contenuto del mio file..potreste dargli un occhiata??? grazie anticipatamente...:inchino:

---------- Post added at 12:46 ---------- Previous post was at 12:43 ----------

Dopo svariati tentativi sono riuscito a scrivere qualcosa seguendo i vostri consigli :
Codice:
typedef struct { 
        char nome[15];
        char cognome[15];
        char via[10];
        int eta;
} Persona;
[/QUOTE]
ah non fate caso alla variazione della struttura..penso che la funzionalità dovrebbe essere la stessa...invece che studenti crea persone...
 
Ho risolto parte dell'esercizio mi manca l'ultima parte la ricerca con la stampa degli elementi appartenenti a quella determinata struttura
Codice:
#include <stdio.h>
#include <ctype.h>
#include<stdlib.h>
#include<string.h>
#define DIM 2


typedef struct { 
        char nome[15];
        char cognome[15];
        int eta;
}Persona;


Persona P[DIM];


int main(){ 
    
    Persona e;
    
    int crea_vettore(Persona V[], int dim);
    void ricerca (FILE *file,char[20],Persona Z[]);
    int  n;
    FILE *file;
    char nome[30];
    printf("Inserisci il nome del file: ");
    gets(nome);
    


    if ((file=fopen(nome, "wb"))==NULL){ 
                          printf("Impossibile aprire file%s\n", nome);
                          return 1;
    }
    n=crea_vettore(P,DIM);
     for(n=0;n<2;n++){
                    fprintf(file,"#\n");  
                    fprintf(file,"%s\n",P[n].nome);
                    fprintf(file,"%s\n",P[n].cognome);
                    fprintf(file,"%d\n\n",P[n].eta);
                    
                    }
     fclose(file);
     
[COLOR=#ff0000][B]char C[50]; [/B][/COLOR]
[COLOR=#ff0000][B]int k=0; [/B][/COLOR]
[COLOR=#ff0000][B]printf("Inserire il cognome da ricercare: "); [/B][/COLOR]
[COLOR=#ff0000][B]scanf("%s",C); [/B][/COLOR]
[COLOR=#ff0000][B]file=fopen(nome, "rb"); [/B][/COLOR]
[COLOR=#ff0000][B] while(fread(&P, sizeof(Persona), 1, file)>0) [/B][/COLOR]
[COLOR=#ff0000][B]     if (!strcmp(P.cognome,C)) [/B][/COLOR]
[COLOR=#ff0000][B]     {  [/B][/COLOR]
[COLOR=#ff0000][B]       printf("ok XD \n"); [/B][/COLOR]
[COLOR=#ff0000][B]       k++; [/B][/COLOR]
[COLOR=#ff0000][B]     } [/B][/COLOR]
[COLOR=#ff0000][B] printf("\n %d cittadini con cognome %s\n",k, C); [/B][/COLOR]
 fclose(file);              
     
    //fwrite(P,sizeof(Persona),n,file);
    


    system("PAUSE");
    return 0;
    }


int crea_vettore(Persona P[], int dim){ 
    int i=0;
    char s[80];
    printf("--- funzione crea_vettore ---\n\n");
    while (!feof(stdin) && i<dim){
          printf("Inserisci nome: "); 
          scanf("%s",&P[i].nome);
          printf("Inserisci cognome: "); 
          scanf("%s",&P[i].cognome);
          printf("Inserisci eta': "); 
          scanf("%d",&P[i].eta);
          printf("\n");
          i++;
    }
   
    return i;
    }

il problema mi sorge quando devo effettuare la ricerca...non mi trova nulla e mi da il seguente errore: request for member `cognome' in something not a structure or union


mentre io vorrei che trovato il cognome mi stampasse anche il nome e l'età...help me please :inchino:
 
Pubblicità
Pubblicità
Indietro
Top