/* campionamento di un file * carica il campione su array * versione "con reimbussolamento", ovvero un record puo' essere preso piu' volte * Il caricamento del campione su array giustificato soltanto se: * 1. il campione che si vuole estrarre non e' troppo grande * 2. l'elaborazione che si intende svolgere sul campione richiede pi accessi * a ogni dato * * - acquisisce nome e apre file da campionare in modalità lettura binaria * - acquisisce origine sequenza random * - si posiziona in coda al file per calcolarne la dimensione N * - input della frazione da campionare n e verifica di capienza dell'array * - ripeti n volte la generazione di un numero fra 0 e N e leggi * il record corrispondente nell'array * - elabora il campione */ #define dimCAMPIONE 10000 #define DIMBUF 80 #include <stdio.h> #include <stdlib.h> #include "random.h" /* procedura esterna per la generazione di numeri random */ typedef long r; /* a titolo di esempio si considera un file di interi lunghi */ void elabora(r *campione,long n); int main(){ r camp[dimCAMPIONE]; /* array di campioni */ long N, /* numero di r nel file */ n, /* dimensione campione corrente */ i, /* indice */ seme, /* seme per rand */ p; /* posizione di campionamento corrente */ float f; /* frazione da estrarre */ FILE *fd; char nomeF[64], linea[DIMBUF]; /* intro e' un array di 4 stringhe di 64 caratteri ciascuna, utilizzato per mandare * all'utente un messaggio introduttivo */ char intro[4][64]={"Programma per il campionamento di record da un file\n", " Richiede il nome del file, il seme della sequenza random e\n", " la frazione di record da campionare.\n", " Versione con caricamento del campione in memoria\n"}; for (i=0;i<4;i++) /* visualizza intro */ printf("%s",intro[i]); /* inizializzazione */ printf("\nNome file da campionare\n"); fgets(linea,DIMBUF,stdin); sscanf(linea,"%s",nomeF); if ((fd=fopen(nomeF,"rb"))==NULL){ printf("File %s non trovato\n",nomeF); return 1; } printf("Inserire origine sequenza random \n"); fgets(linea,DIMBUF,stdin); sscanf(linea,"%ld",&seme); srand(seme); fseek(fd,0,SEEK_END); N=ftell(fd)/sizeof(r); printf("Inserire frazione da campionare (da 0 a 0.5) \n"); fgets(linea,DIMBUF,stdin); sscanf(linea,"%f",&f); n=f*N; printf("Nel file ci sono %ld records, ne campiono %ld\n",N,n); if (n>dimCAMPIONE){ printf("Campione troppo grande\n"); return 1; } /* fine inizializzazione */ for (i=0;i<n;i++){ /* ripete n volte il campionamento */ p=randN(N); /* genera la posizione del record da campionare */ fseek(fd,p*sizeof(r),SEEK_SET); /* si posiziona per la lettura */ fread(&(camp[i]),sizeof(r),1,fd); /* legge il record nell'array */ } fclose(fd); elabora(camp,n); /* elabora l'array con il campione */ return 0; } /* fine main */ /* * elabora: esempio di elaborazione dell'array con il campione */ void elabora(r *campione, long n){ /* a titolo di esempio si calcola la media */ float media; long i; media=campione[0]; for (i=1;i<n;i++) media = (media*(i)+campione[i])/(i+1); printf("valore medio %f\n",media); } /* fine elabora */