Newsgroup: it.comp.lang.c
Titolo: File e Strutture

Ciao a tutti
Allora vi espongo il mio problema ho due file ad accesso sequenziale, in 
cui vengono memorizzati degli elementi chimici.
Es:
11 sodium Na 22.99
20 calcium ca 40.08
e cosi' via.
Ora il mio problema e che devo creare un terzo file ad accesso casuale, 
con il contenuto dei due file precedenti(evitando i duplicati).
io sono riuscito a scrivere questa funzione merge che crea il file ad 
accesso casuale.
Il file ad accesso casuale lo apro nel main.
Inoltre la struttura e' stata così definita.
Quindi la mia domanda e' come faccio a evitare i duplicati?
Vi ringrazio.
Ciao
typedef struct{
         int numero_atomico;
         char nome[COMPOSTO];
         char simbolo[COMPOSTO];
         double peso;
         }chimico_t;
void merge(FILE *composto_1, FILE *composto_2, FILE *composto){
 
      chimico_t chimico;
      chimico_t chimico1;
      chimico_t chimico2;
      composto_1 = fopen("testo.txt", "rb");
      fscanf(composto_1,"%d%s%s%lf",&chimico1.numero_atomico,
                                        chimico1.nome,
                                        chimico1.simbolo,
                                       &chimico1.peso);
       while(!feof(composto_1)){
           fwrite(&chimico1, sizeof(chimico_t), 1, composto);
           fscanf(composto_1,"%d%s%s%lf",&chimico1.numero_atomico,
                                          chimico1.nome,
                                          chimico1.simbolo,
                                         &chimico1.peso);
 
      }
        fclose(composto_1);
        composto_2 = fopen("testo1.txt", "rb");
        fscanf(composto_2,"%d%s%s%lf",&chimico2.numero_atomico,
                                       chimico2.nome,
                                       chimico2.simbolo,
                                      &chimico2.peso);
      while(!feof(composto_2)){
          fwrite(&chimico2, sizeof(chimico_t), 1, composto);
          fscanf(composto_2,"%d%s%s%lf",&chimico2.numero_atomico,
                                         chimico2.nome,
                                         chimico2.simbolo,
                                        &chimico2.peso);
      }
      fclose(composto_2);
      fclose(composto);
}

          }chimico_t;
praticamente il tuo prof di informatica (mi sembra un problema
scolastico) ti chiede di implementare la logica dietro un db.
Detto questo non so se esistono degli algoritmi ad alte prestazioni per
fare il lavoro che vuoi far tu, probabilmente già implementati in
alcune librerie.
Personalmente, prima di creare il file ad accesso casuale, analizzerei
gli elementi all'interno della struttura basandomi su elementi unici
della struttra (esempio: numero_atomico, peso).
Questo metodo, facile da implementare, è veloce quando gli elementi
sono pochi (intorno al migliaio).
Per un elenco + lungo dovresti basarti su algoritmi esistenti.
Se è a livello scolastico, credo che la soluzione da me esposta va
bene.

 
Si sono d'accordo con te, ma il mio problema e' come faccio a 
confrontare i gli elementi?


 confrontare i gli elementi?
Beh te l'ho detto :)
Adesso non sono un genio in chimica, ma mi aspetto che i vari elementi
hanno un peso specifico
ed un numero atomico proprio.
Esempio O:
ha un numero atomico uguale a: 8
ha un peso uguale a (peso atomico): 15,9994 amu
Ipotizzando che hai un array di strutture popolato già da 10 elementi,
dove uno è l'ossigeno, cicli e scarti
quello presto attualmente dal file.
PSEUDOCODICE
for (int i = 0; i < num_di_elementi_in_array; i++)
{
  if (array_strutture_popolato[i].numero_atomico ==
struttura_popolata_dal_file.numero_atomico &&
     array_strutture_popolato[i].peso_atomico ==
struttura_popolata_dal_file.peso_atomico)
  {
    array_strutture_popolato = alloca_memoria_per_elemento_successivo;
// malloc
    copia_struttura(array_strutture_popolato[i+1],
struttura_popolata_dal_file);
  }
}
Non ho voluto toglierti il piacere di scrivere un pò di righe in C :)

 
Graziee :)

 sequenziale che devono essere confrontati.
Carica i due file e tienili in memoria.
Metti i dati dei file nelle strutture e lavori con quelle, più un
terzo arrey di
strutture dove inserirai i dati che ti servono.
Una volta finito prendi quest'ultima struttura e la stampi ciclicamente
sino ad
arrivare all'ultimo elemento dell'array.
Non capisco quale sia il tuo problema.
Se è di concetto o di programmazione.

Ciao Salvatore
grazie per l'aiuto che mi stai dando
Salvatore Di Fazio ha scritto:

Alora ho cambiato le strutture in array,ma il problema e' che non riesco 
a capire dove devo fare il confronto.
void merge(FILE *composto_1, FILE *composto_2, FILE *composto){
     chimico_t chimico[DIM_MAX];
     chimico_t chimico_1[DIM_MAX];
     chimico_t chimico_2[DIM_MAX];
     int i;
     composto_1 = fopen("testo.txt", "rb");
     composto_2 = fopen("testo1.txt", "rb");
     fscanf(composto_1,"%d%s%s%lf",&chimico_1[i].numero_atomico,
                                    chimico_1[i].nome,
                                    chimico_1[i].simbolo,
                                   &chimico_1[i].peso);
     fscanf(composto_2,"%d%s%s%lf",&chimico_2[i].numero_atomico,
                                    chimico_2[i].nome,
                                    chimico_2[i].simbolo,
                                   &chimico_2[i].peso);
     for( i = 0; i < DIM_MAX; i++){
     while(!feof(composto_1)){
         fwrite(&chimico_1, sizeof(chimico_t), 1, composto);
         fscanf(composto_1,"%d%s%s%lf",&chimico_1[i].numero_atomico,
                                        chimico_1[i].nome,
                                        chimico_1[i].simbolo,
                                       &chimico_1[i].peso);
      }
     while(!feof(composto_2)){
         fwrite(&chimico_2, sizeof(chimico_t), 1, composto);
         fscanf(composto_2,"%d%s%s%lf",&chimico_2[i].numero_atomico,
                                        chimico_2[i].nome,
                                        chimico_2[i].simbolo,
                                       &chimico_2[i].peso);
      }
     }
     fclose(composto_1);
     fclose(composto_2);
     fclose(composto);
}

 a capire dove devo fare il confronto.
allora è un problema di concetto il tuo.
Puoi fare il confronto dove vuoi.
Una volta che hai gli array da confrontare, inizi il tuo bel ciclo x
tutti gli elementi e inizia il confronto.
Se non hai l'elemento nell'array che dopo scriverai nel file, lo
inserisci, sennò non lo inserisci.
Alla fine scrivi il file.

Ciao Salvatore
Ciao a tutti,
Purtroppo sto avendo problemi nel confronto tra gli elementi dei due file.
Praticamente scrivo prima il contenuto del primo file. poi cerco di 
controllare se gli elementi del secondo file sono anche nel primo, qndi 
se vi sono li salto.
Ma sbaglio e questo codice mi stà facendo impazzire.
Grazie, spero possiate aiutarmi.
typedef struct{
         int numero_atomico;
         char nome[COMPOSTO];
         char simbolo[COMPOSTO];
         double peso;
         }chimico_t;
nella funzione
void merge(FILE *composto_1, FILE *composto_2, FILE *composto){
 
     chimico_t chimico[DIM_MAX];
     chimico_t chimico_1[DIM_MAX];
     chimico_t chimico_2[DIM_MAX];
     int j;
     int i = 0;
     composto_1 = fopen("testo.txt", "rb");
     composto_2 = fopen("testo1.txt", "rb");
     fscanf(composto_1,"%d%s%s%lf",&chimico_1[i].numero_atomico,
                                    chimico_1[i].nome,
                                    chimico_1[i].simbolo,
                                   &chimico_1[i].peso);
      for( i = 0; i < DIM_MAX; i++){
      while(!feof(composto_1)){
          fwrite(&chimico_1, sizeof(chimico_t), 1, composto);
          fscanf(composto_1,"%d%s%s%lf",&chimico_1[i].numero_atomico,
                                         chimico_1[i].nome,
                                         chimico_1[i].simbolo,
                                        &chimico_1[i].peso);
      }
}
     fscanf(composto_2,"%d%s%s%lf",&chimico_2[j].numero_atomico,
                                    chimico_2[j].nome,
                                    chimico_2[j].simbolo,
                                   &chimico_2[j].peso);
     for(j = 0; j < DIM_MAX; j++){
         while(!feof(composto_2)){
             if(chimico_2[j].nome != chimico_1[i].nome){
                 fwrite(&chimico_2, sizeof(chimico_t), 1, composto);
 
fscanf(composto_2,"%d%s%s%lf",&chimico_2[j].numero_atomico,
                                        chimico_2[j].nome,
                                        chimico_2[j].simbolo,
                                       &chimico_2[j].peso);
    }
   }
                 fscanf(composto_1,"%d%s%s%lf",&chimico_1[i].numero_atomico,
                                         chimico_1[i].nome,
                                         chimico_1[i].simbolo,
                                        &chimico_1[i].peso);
   i++;
   }
     fclose(composto_1);
     fclose(composto_2);
     fclose(composto);
}

 Ma sbaglio e questo codice mi stà facendo impazzire.
La soluzione di Salvatore Di Fazio mi sembra più che ragionevole. Il mio 
suggerimento è:
1) fai una funzione che legge un file e riempe un array di chimico_t. 
Ritorna anche il numero di elementi letti.
2) usa questa funzione e carica i file composto_1 e composto_2 negli array 
chimico_1 e chimico_2.
3) a questo punto hai due array con tutti i tuoi elementi. Chiudi i file 
composto_1 e composto_2 che tanto non ti servono più.
4) costruisci un array chimico_merge. Come prima cosa ci copi dentro tutto 
chimico_1. Poi scorri chimico_2 e per ogni elemento lo confronti con tutti 
gli elementi di chimico_1 e se ne trovi uno uguale, allora passi al 
successivo. Se non trovi alcun elemento uguale, lo inserisci in 
chimico_merge.
5) fai una funzione che scrive il contenuto di un array di chimico_t su file 
e usala.
Questa soluzione è la più lenta del mondo, ma è anche la più facile. 
Ovviamente si suppone che i singoli file non abbiano duplicati al loro 
interno.
Per la cronaca, è il caso che studi meglio il C. Il confronto tra array di 
caratteri non si fa con:
chimico_2[j].nome != chimico_1[i].nome
ma con:
strcmp(chimico_2[j].nome,chimico_1[i].nome)!=0
Quando hai fatto, posta la soluzione.
-- 
Costantino Grana 

ok io farei cosi', ma forse non ho capito bene...
diciamo che gli elemtni in natura siano 100
allora facciamo un bel array di 100 strutture (elemento_info
arrayElementi[100])
il numero atomico nn fa parte della struttura, perche'  lo uso come
indice dell'array
cioe' lil sodio sara' ad esempio in posizione 10 (il primo elemtno ha
numero atomico 1 giusto?quidni shifto giu' di 1)
ora hai un campo del,la struttura che e' ad esempio "trovato"
leggo un file, man mano che trovo guardo se il campo trovato
dell'elemtno nell'array e' settato:
a) leggo il sodio;num atomico 11
b) guardo arrayElementi[10].trovato; se vale 1 allora l'ho gia' trovato
in precedenza, altrimenti non l'ho mai trovato
c) setto arrayElementi[10].trovato = 1
Claudio ha scritto:
