Modifica di un file ad accesso casuale

di il
3 risposte

Modifica di un file ad accesso casuale

Nella traccia d'esame che stavo svolgendo era richiesta la creazione di un file in cui vanno scritti i dati contenuti in un vettore e successivamente la lettura e la modifica del file appena creato. Nello specifico i dati vengono generati direttamente dal programma e allo stesso modo il programma stesso dovrebbe modificarli distinguendo tra pari e dispari.
Di seguito il codice e subito dopo una spiegazione più dettagliata:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define DIMMAX 500
#define RANDOM 10

struct structVet {
	int array[DIMMAX];
	int dimensione;
};

struct structValFreq {
	float valore;
	int frequenza;
};

typedef struct structVet StructVet;
typedef struct structValFreq StructValFreq;

void init(StructVet *VET);
void stampa(StructVet *VET);
void statistiche(StructVet *VET, float *media, float *devStd);
void calcolaStampaIsto(StructVet *VET, StructVet *ISTO);
void minMax(StructVet *ISTO, StructValFreq *minimo, StructValFreq *massimo);
void generaFile(StructVet *ISTO, FILE *wPtr);
void stampaFile(FILE *wPtr);
void aggiornaFile(FILE *wPtr);

int main(int argc, char *argv[]) {
	
	StructVet vettore;
	StructVet istogramma;
	float med, deviazione;
	StructValFreq min;
	StructValFreq max;
	FILE *fPtr;
	int scelta;
	srand(time(NULL));
	
	while (scelta!=9){
		printf("\nInserire un intero per scegliere un'opzione\n");
		printf("1: Inizializza vettore di massimo 500 elementi\n");
		printf("2: Stampa vettore formattato\n");
		printf("3: Calcola media e deviazione standard\n");
		printf("4: Stampa istogramma\n");
		printf("5: Trova minimo e massimo\n");
		printf("6: Crea file\n");
		printf("7: Stampa file\n");
		printf("8: Aggiorna file\n");
		printf("9: Termina programma\n\n");
		scanf("%d", &scelta);
		
		switch(scelta){
			case 1:
				init(&vettore);
				break;
				
			case 2:
				stampa(&vettore);
				break;
				
			case 3:
				statistiche(&vettore, &med, &deviazione);
				printf("Media: %.2f\nDeviazione Standard: %.2f\n", med, deviazione);
				break;
				
			case 4:
				calcolaStampaIsto(&vettore, &istogramma);
				break;
				
			case 5:
				minMax(&istogramma, &min, &max);
				printf("Valore minimo: %.0f\nFrequenza: %d\nValore massimo: %.0f\nFrequenza: %d\n", min.valore, min.frequenza, max.valore, max.frequenza);
				break;
				
			case 6:
				generaFile(&istogramma, fPtr);
				break;
				
			case 7:
				stampaFile(fPtr);
				break;
				
			case 8:
				aggiornaFile(fPtr);
				printf("Stampare il file aggiornato? (s/n)\n");
				char c;
				scanf("%*c%c", &c);
				
				if(c == 's'){
					stampaFile(fPtr);
				}
				break;
				
			case 9: 
				break;
				
			default:
				break;
				
		}
		if(scelta<1 || scelta>9){
			printf("ERRORE! Inserire un'opzione valida\n");
		}
	}
	
	printf("Programma terminato.\n");
	 
	return 0;
}

void init(StructVet *VET){
	int i;
	for(i=0; i<DIMMAX; i++){
		VET->array[i] = 0;
	}
	VET->dimensione = 100;
	
	for(i=0; i<VET->dimensione; i++){
		VET->array[i] = rand() % RANDOM;
	}
	printf("Vettore inizializzato con successo!\n");
}

void stampa(StructVet *VET){
	int i, j;
	for(i=0; i<10; i++){
		for(j=0; j<100; j++){
			if(VET->array[j] == i){
				printf("%d", VET->array[j]);
			}
		}
		puts("");
	}
}

void statistiche(StructVet *VET, float *media, float *devStd){
	int i;
	int somma = 0;
	for(i=0; i<VET->dimensione; i++){
		somma += VET->array[i];
	}
	*media =  somma / VET->dimensione;
	
	float sommaScarti = 0;
	float scarto;
	for(i=0; i<VET->dimensione; i++){
		scarto = (*media - VET->array[i]) * (*media - VET->array[i]);
		sommaScarti += scarto;
	}
	*devStd = sqrt(sommaScarti) / VET->dimensione;
}

void calcolaStampaIsto(StructVet *VET, StructVet *ISTO){
	int i, j;
	for(i=0; i<DIMMAX; i++){
		ISTO->array[i] = 0;
	}
	
	ISTO->dimensione = 10;
	
	for(i=0; i<VET->dimensione; i++){
		ISTO->array[VET->array[i]]++;
	}
	
	for(i=0; i<ISTO->dimensione; i++){
		printf("%d:  ", i);
		for(j=0; j<ISTO->array[i]; j++){
			printf("*");
		}
		puts("");
	}
}

void minMax(StructVet *ISTO, StructValFreq *minimo, StructValFreq *massimo){
	minimo->valore = 0;
	minimo->frequenza = ISTO->array[0];
	massimo->valore = 0;
	massimo ->frequenza = ISTO->array[0];

	int i;
	for(i=1; i<ISTO->dimensione; i++){
		if(minimo->frequenza>ISTO->array[i]){
			minimo->valore = i;
			minimo->frequenza = ISTO->array[i];
		}
		if(massimo->frequenza<ISTO->array[i]){
			massimo->valore = i;
			massimo->frequenza = ISTO->array[i];
		}
	}
}

void generaFile(StructVet *ISTO, FILE *wPtr){
	if((wPtr = fopen("data.txt", "w")) == NULL){
		printf("Impossibile aprire il file\n");
	}
	else{
		StructValFreq DATI;
		int i;
		for(i=0; i<ISTO->dimensione; i++){
			DATI.valore = i;
			DATI.frequenza = ISTO->array[i];
			fwrite(&DATI, sizeof(StructValFreq), 1, wPtr);
		}
		fclose(wPtr);
		printf("Programma creato con successo!\n");
	}
}

void stampaFile(FILE *wPtr){
	if((wPtr = fopen("data.txt", "r")) == NULL){
		printf("Impossibile aprire il file\n");
	}
	else{
		StructValFreq DATI;
		int i;
		while(!feof(wPtr)){
			StructValFreq DATI;
			int record = fread(&DATI, sizeof(StructValFreq), 1, wPtr);
			if(record != 0){
				printf("%.2f    %d\n", DATI.valore, DATI.frequenza);
			}
		}
		fclose(wPtr);
		printf("Programma stampato con successo!\n");
	}
}

void aggiornaFile(FILE *wPtr){
	if((wPtr = fopen("data.txt", "r+")) == NULL){
		printf("Impossibile aprire il file\n");
	}
	else{
		StructValFreq DATI;
		int i;
		for(i=0; i<10; i++){
			fseek(wPtr, i * sizeof(StructValFreq), SEEK_SET);
			fread(&DATI, sizeof(StructValFreq), 1, wPtr);
				if((DATI.frequenza)%2==0){
					DATI.valore = DATI.valore * 2;
				}
				else{
					DATI.valore = DATI.valore / 2;
				}
				fwrite(&DATI, sizeof(StructValFreq), 1, wPtr);
		}
		fclose(wPtr);
		printf("Programma aggiornato con successo!\n");
	}
}
Dunque, il programma utilizza 8 funzioni che, attraverso dei puntatori a strutture definite all'inizio, inizializzano un vettore e un istogramma che lo rappresenta e infine creano un file in cui sostanzialmente sono riportate le informazioni della struttura istogramma (l'indice di ISTO.array diventa DATI.valore e il valore di ISTO.array diventa DATI.frequenza).
Tutte le funzioni lavorano correttamente fatta eccezione per l'ultima (aggiornaFile) che dovrebbe leggere i dati dal file, verificare se DATI.frequenza è pari o dispari e in un caso raddoppiare DATI.valore mentre nell'altro dimezzarlo lasciando invariato DATI.frequenza.
Quando stampo il programma aggiornato però non è cambiato nulla, i dati non sono stati modificati.
Io penso che ci possa essere un errore nella lettura dei dati, di fatto non sono molto pratico con i file e sul libro gli esempi sono molto pochi.
Spero possiate aiutarmi, grazie in anticipo.

3 Risposte

Devi accedere o registrarti per scrivere nel forum
3 risposte