ordinare liste contenute in file [C]

Pubblicità

Trigun86

Utente Attivo
Messaggi
24
Reazioni
0
Punteggio
25
Sera a tutti come da titolo ho questo problema devo ordinare in ordine di età le liste contenute in un file:

Codice:
#include<stdio.h>#include<stdlib.h>
#include<string.h>


struct persona {
       char nome[20];
       char cognome[20];
       int anni;
       };
       
void crea_file(char *);
struct persona crea_s();
void vedi_file(char *);
void stampa(struct persona);
void cerca(char *);
void copia (char *);
int ordina (struct persona[], int n);


int main(){
    char v[20];
    printf("***\t Welcome to ex 01 =D *** \n\n\n");
    printf("Inserire nome file da creare: ");
    scanf("%s",&v);
    
    crea_file(v);
    vedi_file(v);
    cerca(v);
    copia(v);


    
    system("PAUSE");
    return 0;
}


void crea_file(char *v){
     
     struct persona p;
     
     FILE *fp;
     int fine=0;
     int numero=0;
     if((fp=fopen(v,"wb"))==NULL){
                                  printf("Errore apertura file -.-' \n");
                                  }
     
     while(!fine){
                  p=crea_s();
                  fwrite(&p,sizeof(struct persona),1,fp);
                  printf("FINE SI=1, NO=0 ");
                  scanf("%d",&fine);
                  }
     printf("Quale persona vuoi stampare:");
     scanf("%d",&numero);
     fseek(fp,(numero)*sizeof(struct persona),SEEK_SET);
     fread(&p,sizeof(struct persona),1,fp);
     printf("\n%s",p.nome);
                  fclose(fp);
}


struct persona crea_s(){
       struct persona p;
       
       printf("\nNome: ");
       scanf("%s",p.nome);
       printf("\nCognome: ");
       scanf("%s",p.cognome);
       printf("\nAnni: ");
       scanf("%d",&p.anni);
       
       return p;
}


void vedi_file(char *v){
     struct persona p;
    
     FILE *fp;
     int k=0;
     
     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore! \n");
                                  }
     fread(&p,sizeof(struct persona),1,fp);
     
     while(!feof(fp)){
                      stampa(p);
                      fread(&p,sizeof(struct persona),1,fp);
                      k++;
                      }
                      printf("%d",k);
     struct persona a[k];
     ordina(a,k);
     fclose(fp);
     }
     
void stampa(struct persona p){
     printf("\n*************************\n");
     printf("* Nome: %s\n",p.nome);
     printf("* Cognome: %s\n",p.cognome);
     printf("* Anni: %d\n",p.anni);
     printf("*************************\n");
}


void cerca(char *v){
     struct persona p;
     FILE *fp;
     char c[20];
     int k=0;
     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore!\n");
                                  }
     printf("Inserisci il cognome da ricercare: ");
     scanf("%s",c);
     
     while(fread(&p,sizeof(struct persona),1,fp)>0)
     if(!strcmp(p.cognome,c)){
                              printf("Trovato\n");
                              stampa(p);
                              }
                              fclose(fp);
     }                  


void copia(char *v){
     struct persona p;
     FILE *f_in, *f_out;
     int buf[500];
     char nf[20];
     
     printf("Nome file in cui si vuol copiare:\n");
     scanf("%s",nf);
     
     if((f_in=fopen(v,"rb")) && (f_out=fopen(nf,"wb"))){
                             size_t b;
                             while(b=fread(buf,1,500,f_in))
                                     fwrite(buf,1,500,f_out);
                                     }
     fclose(f_in);
     fclose(f_out);
     }


[COLOR=#ff0000]int ordina(struct persona a[], int n){[/COLOR]
     
     int i, j;
     int temp;
     
     j=i;
     
     for(i=0;i<n-1;i++){
         for(j=0;j<n-1-i;j++)
         if(a[j].anni>a[j+1].anni){
                   temp=a[j].anni;
                   a[j].anni=a[j+1].anni;
                   a[j+1].anni=temp;
         
                   }
            
     }
     printf("le date in ordine non decrescente : ");
    
     for(i=0;i<n;i++){
          
          printf("\n%s %s %d\n", a[i].nome, a[i].cognome, &a[i].anni);
          }
    
}
il mio problema sorge qui... int ordina(struct persona a[], int n){....... nel momento della stampa mi escono caratteri incomprensibili aiuto...ho una consegna domani.. grazie :D
 
Ecco:
Codice:
#include<stdio.h>#include<stdlib.h>
#include<string.h>




struct persona {
       char nome[20];
       char cognome[20];
       int anni;
       };


void crea_file(char *);
struct persona crea_s();
void vedi_file(char *);
void stampa(struct persona);
void cerca(char *);
void copia (char *);
int ordina (struct persona[], int n);
[FONT=arial black][COLOR=#ff0000]int numero_totale_persone = 0;[/COLOR][/FONT]


int main(){
    char v[20];
    printf("***\t Welcome to ex 01 =D *** \n\n\n");
    printf("Inserire nome file da creare: ");
    scanf("%s",&v);


    crea_file(v);
    vedi_file(v);
    cerca(v);
    copia(v);






    system("PAUSE");
    return 0;
}




void crea_file(char *v){


     struct persona p;


     FILE *fp;
     int fine=0;
     int numero=0;
     if((fp=fopen(v,"wb"))==NULL){
                                  printf("Errore apertura file -.-' \n");
                                  }


     while(!fine){
                  p=crea_s();
                  fwrite(&p,sizeof(struct persona),1,fp);
                  numero_totale_persone++;
                  printf("Persone totali: %d\n", numero_totale_persone);
                  printf("FINE SI=1, NO=0 ");
                  scanf("%d",&fine);
                  }
     printf("Quale persona vuoi stampare:");
     scanf("%d",&numero);
     fseek(fp,(numero)*sizeof(struct persona),SEEK_SET);
     fread(&p,sizeof(struct persona),1,fp);
     printf("\n%s",p.nome);
                  fclose(fp);
}




struct persona crea_s(){
       struct persona p;


       printf("\nNome: ");
       scanf("%s",p.nome);
       printf("\nCognome: ");
       scanf("%s",p.cognome);
       printf("\nAnni: ");
       scanf("%d",&p.anni);


       return p;
}




void vedi_file(char *v){
     struct persona p;
[FONT=arial black][COLOR=#ff0000]     struct persona a[numero_totale_persone];[/COLOR][/FONT]
     FILE *fp;
     int k=0;


     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore! \n");
                                  }
     fread(&p,sizeof(struct persona),1,fp);
[FONT=arial black][COLOR=#ff0000]     a[k] = p;[/COLOR][/FONT]
     while(!feof(fp)){
                      stampa(p);
                      fread(&p,sizeof(struct persona),1,fp);
                      k++;
[FONT=arial black][COLOR=#ff0000]                      a[k] = p;[/COLOR][/FONT]
                      }
                      printf("%d",k);
     ordina(a,k);
     fclose(fp);
     }


void stampa(struct persona p){
     printf("\n*************************\n");
     printf("* Nome: %s\n",p.nome);
     printf("* Cognome: %s\n",p.cognome);
     printf("* Anni: %d\n",p.anni);
     printf("*************************\n");
}




void cerca(char *v){
     struct persona p;
     FILE *fp;
     char c[20];
     int k=0;
     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore!\n");
                                  }
     printf("Inserisci il cognome da ricercare: ");
     scanf("%s",c);


     while(fread(&p,sizeof(struct persona),1,fp)>0)
     if(!strcmp(p.cognome,c)){
                              printf("Trovato\n");
                              stampa(p);
                              }
                              fclose(fp);
     }




void copia(char *v){
     struct persona p;
     FILE *f_in, *f_out;
     int buf[500];
     char nf[20];


     printf("Nome file in cui si vuol copiare:\n");
     scanf("%s",nf);


     if((f_in=fopen(v,"rb")) && (f_out=fopen(nf,"wb"))){
                             size_t b;
                             while(b=fread(buf,1,500,f_in))
                                     fwrite(buf,1,500,f_out);
                                     }
     fclose(f_in);
     fclose(f_out);
     }




int ordina(struct persona a[], int n){


     int i, j;
     int temp;


     j=i;


    for(i=0;i<n-1;i++){
         for(j=0;j<n-1-i;j++)
         if(a[j].anni>a[j+1].anni){
                   temp=a[j].anni;
                   a[j].anni=a[j+1].anni;
                   a[j+1].anni=temp;


                   }


     }


     printf("le date in ordine non decrescente : ");


     for(i=0;i<n;i++){


          printf("\n Nome- %s \nCognome- %s \nAnni-%d", a[i].nome, a[i].cognome, a[i].anni);
          }


}
Nell'array non ci mettevi nulla praticamente..
Poi la funzione ordine è proprio sbagliata..Nel senso che non fai altro che dare ad una persona gli anni di un altra..quindi non è giusto il metodo che usi..
 
Ciao,

così sistemato da me dovrebbe funzionare, non ho provato a compilare perchè vado di fretta.
Se da qualche errore, rispondi pure che provo ad aiutarti :D

Codice:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>


struct persona {
       char nome[20];
       char cognome[20];
       int anni;
       };
       
void crea_file(char *);
struct persona crea_s();
void vedi_file(char *);
void stampa(struct persona);
void cerca(char *);
void copia (char *);
void  mergeSortS(struct persona[] , int, int, struct persona *);

int compare(struct persona el1, struct persona el2)
{
    if (el1.anni > el2.anni)
        return 1;
    if (el1.anni < el2.anni)
        return -1;
    if (el1.anni == el2.anni)
        return strcmp(el1.cognome,el2.cognome);
}

void mergeS(struct persona v[], int i1, int i2, int fine, struct persona vout[]) {
int i=i1, j=i2, k=i1;
while ( i <= i2-1 && j <= fine ) {
if (compare(v[i], v[j]) < 0) {
vout[k] = v[i];
i++;
}
else {
vout[k] = v[j];
j++;
}
k++;
}
while (i<=i2-1) {
vout[k]=v[i];
i++; k++;
}
while (j<=fine) {
vout[k]=v[j];
j++; k++;
}
for (i=i1; i<=fine; i++) v[i] = vout[i];
}

void mergeSortS(struct persona * v, int iniz, int fine, struct persona vout[]) {
int mid;
if ( iniz < fine ) {
mid = (fine + iniz) / 2;
mergeSortS(v, iniz, mid, vout);
mergeSortS(v, mid+1, fine, vout);
mergeS(v, iniz, mid+1, fine, vout);
}
}

int main(){
    char v[20];
    printf("***\t Welcome to ex 01 =D *** \n\n\n");
    printf("Inserire nome file da creare: ");
    scanf("%s",&v);
    
    crea_file(v);
    vedi_file(v);
    cerca(v);
    copia(v);


    
    system("PAUSE");
    return 0;
}


void crea_file(char *v){
     
     struct persona p;
     
     FILE *fp;
     int fine=0;
     int numero=0;
     if((fp=fopen(v,"wb"))==NULL){
                                  printf("Errore apertura file -.-' \n");
                                  }
     
     while(!fine){
                  p=crea_s();
                  fwrite(&p,sizeof(struct persona),1,fp);
                  printf("FINE SI=1, NO=0 ");
                  scanf("%d",&fine);
                  }
     printf("Quale persona vuoi stampare:");
     scanf("%d",&numero);
     fseek(fp,(numero)*sizeof(struct persona),SEEK_SET);
     fread(&p,sizeof(struct persona),1,fp);
     printf("\n%s",p.nome);
                  fclose(fp);
}


struct persona crea_s(){
       struct persona p;
       
       printf("\nNome: ");
       scanf("%s",p.nome);
       printf("\nCognome: ");
       scanf("%s",p.cognome);
       printf("\nAnni: ");
       scanf("%d",&p.anni);
       
       return p;
}


void vedi_file(char *v){
     struct persona p[100];
     struct persona  *b;
     FILE *fp;
     int i;
     int k=0;
     
     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore! \n");
                                  }
     fread(&p[k],sizeof(struct persona),1,fp);
     
     while(!feof(fp)){
                      stampa(p[k]);
                       k++;
                      fread(&p[k],sizeof(struct persona),1,fp);
                      }
                      printf("%d",k);

     b = (struct persona *) malloc( sizeof(struct persona) * k);
     mergeSortS(p,0,k-1,b);
       for(i=0;i<k;i++)
           printf("\n%s %s %d\n", b[i].nome, b[i].cognome, b[i].anni);
     fclose(fp);
     }
     
void stampa(struct persona p){
     printf("\n*************************\n");
     printf("* Nome: %s\n",p.nome);
     printf("* Cognome: %s\n",p.cognome);
     printf("* Anni: %d\n",p.anni);
     printf("*************************\n");
}


void cerca(char *v){
     struct persona p;
     FILE *fp;
     char c[20];
     int k=0;
     if((fp=fopen(v,"rb"))==NULL){
                                  printf("Errore!\n");
                                  }
     printf("Inserisci il cognome da ricercare: ");
     scanf("%s",c);
     
     while(fread(&p,sizeof(struct persona),1,fp)>0)
     if(!strcmp(p.cognome,c)){
                              printf("Trovato\n");
                              stampa(p);
                              }
                              fclose(fp);
     }                  


void copia(char *v){
     struct persona p;
     FILE *f_in, *f_out;
     int buf[500];
     char nf[20];
     
     printf("Nome file in cui si vuol copiare:\n");
     scanf("%s",nf);
     
     if((f_in=fopen(v,"rb")) && (f_out=fopen(nf,"wb"))){
                             size_t b;
                             while(b=fread(buf,1,500,f_in))
                                     fwrite(buf,1,500,f_out);
                                     }
     fclose(f_in);
     fclose(f_out);
     }

Aggiornamento!: Ho provato a compilare il programma e ho notato numerosi problemi di progettazione e di fondamentali del C, come per creare un array di persone ordinate bisogna allocare dinamicamente il vettore altrimenti è impossibile inizializzarlo in run-time.
Ho sistemato un pò di codice e adesso dovrebbe funzionare.
 
Ultima modifica:
grazie a tutti per l'aiuto :) ..

---------- Post added at 09:16 ---------- Previous post was at 09:14 ----------

Ciao,

così sistemato da me dovrebbe funzionare, non ho provato a compilare perchè vado di fretta.
Se da qualche errore, rispondi pure che provo ad aiutarti :D

Codice:
void  mergeSortS(struct persona[] , int, int, struct persona *);

int compare(struct persona el1, struct persona el2)
{
    if (el1.anni > el2.anni)
        return 1;
    if (el1.anni < el2.anni)
        return -1;
    if (el1.anni == el2.anni)
        return strcmp(el1.cognome,el2.cognome);
}

void mergeS(struct persona v[], int i1, int i2, int fine, struct persona vout[]) {
int i=i1, j=i2, k=i1;
while ( i <= i2-1 && j <= fine ) {
if (compare(v[i], v[j]) < 0) {
vout[k] = v[i];
i++;
}
else {
vout[k] = v[j];
j++;
}
k++;
}
while (i<=i2-1) {
vout[k]=v[i];
i++; k++;
}
while (j<=fine) {
vout[k]=v[j];
j++; k++;
}
for (i=i1; i<=fine; i++) v[i] = vout[i];
}

void mergeSortS(struct persona * v, int iniz, int fine, struct persona vout[]) {
int mid;
if ( iniz < fine ) {
mid = (fine + iniz) / 2;
mergeSortS(v, iniz, mid, vout);
mergeSortS(v, mid+1, fine, vout);
mergeS(v, iniz, mid+1, fine, vout);
}
}



     b = (struct persona *) malloc( sizeof(struct persona) * k);
     mergeSortS(p,0,k-1,b);
       for(i=0;i<k;i++)
           printf("\n%s %s %d\n", b[i].nome, b[i].cognome, b[i].anni);
     fclose(fp);
     }
potresti, se per te non è un problema spiegarmi qsti passaggi?
 
Allora partiamo dal basso:
Codice:
b = (struct persona *) malloc( sizeof(struct persona) * k);
questa istruzione alloca dinamicamente un array di puntatori a tipo struct persona grande k.
Codice:
mergeSortS(p,0,k-1,b);
invoca la funzione di ordinamento del vettore di struct persona e come parametri gli vengono dati:
- il vettore p con dentro tutte le struct persona non ordinate.
- il valore iniziale da cui iniziare ad ordinare
- il valore finale, ovvero il numero di struct persona presenti nell'array p - 1.
- il vettore di uscita b creato precedentemente dove saranno presenti i riferimenti alle struct persona ordinate.
Codice:
void mergeS(struct persona v[], int i1, int i2, int fine, struct persona vout[]) { int i=i1, j=i2, k=i1; while ( i <= i2-1 && j <= fine ) { if (compare(v[i], v[j]) < 0) { vout[k] = v[i]; i++; } else { vout[k] = v[j]; j++; } k++; } while (i<=i2-1) { vout[k]=v[i]; i++; k++; } while (j<=fine) { vout[k]=v[j]; j++; k++; } for (i=i1; i<=fine; i++) v[i] = vout[i]; }  void mergeSortS(struct persona * v, int iniz, int fine, struct persona vout[]) { int mid; if ( iniz < fine ) { mid = (fine + iniz) / 2; mergeSortS(v, iniz, mid, vout); mergeSortS(v, mid+1, fine, vout); mergeS(v, iniz, mid+1, fine, vout); } }
Questo e' l'algoritmo di ordinamento Merge Sort uno dei piu' efficienti, ce ne sono molti altri che sono anche piu' semplici da implementare ma meno "veloci".
Questo algoritmo e' fatto in modo che puo' andare bene per qualsiasi tipo di dato, struttura ecc.
Infatti per decidere in che modo ordinare il vettore o la lista ci avvaliamo della funzione compare.
Codice:
int compare(struct persona el1, struct persona el2) {     if (el1.anni > el2.anni)         return 1;     if (el1.anni < el2.anni)         return -1;     if (el1.anni == el2.anni)         return strcmp(el1.cognome,el2.cognome); }[FONT=monospace][/FONT]
Nella funzione compare decidiamo noi in che modo confrontare due elementi dello stesso tipo di dato e valutare quale elemento e' maggiore, minore o uguale ad un altro.
Il valore di ritorno indica alla Merge Sort in quale ordine inserire i vari elementi da ordinare.
 
Allora partiamo dal basso:
Codice:
b = (struct persona *) malloc( sizeof(struct persona) * k);
questa istruzione alloca dinamicamente un array di puntatori a tipo struct persona grande k.
Codice:
mergeSortS(p,0,k-1,b);
invoca la funzione di ordinamento del vettore di struct persona e come parametri gli vengono dati:
- il vettore p con dentro tutte le struct persona non ordinate.
- il valore iniziale da cui iniziare ad ordinare
- il valore finale, ovvero il numero di struct persona presenti nell'array p - 1.
- il vettore di uscita b creato precedentemente dove saranno presenti i riferimenti alle struct persona ordinate.
Codice:
void mergeS(struct persona v[], int i1, int i2, int fine, struct persona vout[]) { int i=i1, j=i2, k=i1; while ( i <= i2-1 && j <= fine ) { if (compare(v[i], v[j]) < 0) { vout[k] = v[i]; i++; } else { vout[k] = v[j]; j++; } k++; } while (i<=i2-1) { vout[k]=v[i]; i++; k++; } while (j<=fine) { vout[k]=v[j]; j++; k++; } for (i=i1; i<=fine; i++) v[i] = vout[i]; }  void mergeSortS(struct persona * v, int iniz, int fine, struct persona vout[]) { int mid; if ( iniz < fine ) { mid = (fine + iniz) / 2; mergeSortS(v, iniz, mid, vout); mergeSortS(v, mid+1, fine, vout); mergeS(v, iniz, mid+1, fine, vout); } }
Questo e' l'algoritmo di ordinamento Merge Sort uno dei piu' efficienti, ce ne sono molti altri che sono anche piu' semplici da implementare ma meno "veloci".
Questo algoritmo e' fatto in modo che puo' andare bene per qualsiasi tipo di dato, struttura ecc.
Infatti per decidere in che modo ordinare il vettore o la lista ci avvaliamo della funzione compare.
Codice:
int compare(struct persona el1, struct persona el2) {     if (el1.anni > el2.anni)         return 1;     if (el1.anni < el2.anni)         return -1;     if (el1.anni == el2.anni)         return strcmp(el1.cognome,el2.cognome); }
Nella funzione compare decidiamo noi in che modo confrontare due elementi dello stesso tipo di dato e valutare quale elemento e' maggiore, minore o uguale ad un altro.
Il valore di ritorno indica alla Merge Sort in quale ordine inserire i vari elementi da ordinare.


grazie per avermi dedicato il tuo tempo... e trasmesso il tuo sapere...
gentilissimo..
 
Pubblicità
Pubblicità
Indietro
Top