Salta ai contenuti. | Salta alla navigazione

Strumenti personali

Soluzione esame 15 Giugno 2017

C source code icon mainGiugno.c — C source code, 4 kB (4445 bytes)

Contenuto del file

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NOME_PRODOTTO 50

// Definizione del prodotto
typedef struct _prodotto {
	char nome[NOME_PRODOTTO];
	int numero_scatole;
} prodotto;

// Rappresentazione di un generico nodo dell'albero binario di ricerca
typedef struct _nodo_albero
{
	struct _nodo_albero* padre;
	prodotto dato;
	struct _nodo_albero* sinistra;
	struct _nodo_albero* destra;
} nodo_albero;

// Comparazione dei due prodotti per nome
int compara_prodotti(prodotto p1, prodotto p2) {
	return strcmp(p1.nome, p2.nome);
}

// Inserisco il prodotto in maniera ordinata nell'albero e copio il contenuto
// della struttura data
nodo_albero* inserimento_ordinato(nodo_albero* t, prodotto p) {
	// Creo un nuovo nodo
	nodo_albero* nodo = (nodo_albero*)malloc(sizeof(nodo_albero));
	// Copio i valori letti dal file
	strcpy(nodo->dato.nome, p.nome);
	nodo->dato.numero_scatole = p.numero_scatole;
	// Inizializzo i puntatori del nodo
	nodo->sinistra = NULL;
	nodo->destra = NULL;
	nodo->padre = NULL;

	// Salvo la radice
	nodo_albero* corrente = t;
	// Controlla che l'albero non sia vuoto
	if (t == NULL) {
		// L'albero � vuoto, impostiamo la radice e ritorniamo
		return nodo;
	}
	// Scorri fino a trovare il primo spazio libero
	nodo_albero* radice = t;
	// Prima o poi la fine � raggiunta
	int stop = 0;
	while (!stop) {
		int cmp = compara_prodotti(p, corrente->dato);
		if (cmp == 0) {
			// I prodotti sono uguali, incrementa il valore delle scatole
			corrente->dato.numero_scatole += p.numero_scatole;
			stop = 1;
		}
		else {
			// Se non � finito, spostati al successivo nodo ordinato, se esiste
			if (cmp < 0) {
				if (corrente->sinistra) corrente = corrente->sinistra; // Prodotto minore, spostati a sinistra
				else {
					// Inserisci qua, spazio libero
					corrente->sinistra = nodo;
					nodo->padre = corrente;
					stop = 1;
				}
			}
			else {
				if (corrente->destra) corrente = corrente->destra; // Prodotto maggiore, spostati a destra
				else {
					// Inserisci qua, spazio libero
					corrente->destra = nodo;
					nodo->padre = corrente;
					stop = 1;
				}
			}
		}
	}
	// Restituisci la radice
	return t;
}

// Creare un albero binario di ricerca che contiene tutti i dati dei prodotti, senza
// duplicati in copia unica come nome e come somma del numero di scatole ordinato in
// base al nome del prodotto. Restituisce la radice dell'albero
nodo_albero* funzioneA(FILE* f_bin, FILE* f_txt, nodo_albero* t) {
	// Lettura del file binario
	prodotto buffer;
	nodo_albero* radice = t;

	// Leggi ed inserisci file binario
	while (fread(&buffer, sizeof(buffer), 1, f_bin)) {
		// Letto un elemento, inserisco nell'albero
		t = inserimento_ordinato(t, buffer);
	}
	// Leggi ed inserisci file testuale
	while (!feof(f_txt)) {
		// Leggo da file di testo l'elemento alla riga corrispondente
		fscanf(f_txt, "%s %d ", &(buffer.nome), &(buffer.numero_scatole));
		t = inserimento_ordinato(t, buffer);
	}
	return t;
}

// Stampare a video il contenuto ordinato dell'albero
void funzioneB(nodo_albero* t) {
	// Parti da sinistra, scorri fino ad arrivare a destra
	nodo_albero* nodo = (nodo_albero*)t;
	if (nodo->sinistra) funzioneB(nodo->sinistra);
	// Stampa il nodo corrente altrimenti � sfasato, prima di andare a destra
	printf("%s, %d\n", nodo->dato.nome, nodo->dato.numero_scatole);
	if (nodo->destra) funzioneB(nodo->destra);
}

// Stampare su file di testo l'albero
void funzioneC(nodo_albero* t, FILE* f_out) {
	// Parti da sinistra, scorri fino ad arrivare a destra
	nodo_albero* nodo = (nodo_albero*)t;
	if (nodo->sinistra) funzioneC(nodo->sinistra, f_out);
	// Stampa il nodo corrente altrimenti � sfasato, prima di andare a destra
	fprintf(f_out, "%s, %d\n", nodo->dato.nome, nodo->dato.numero_scatole);
	if (nodo->destra) funzioneC(nodo->destra, f_out);
}

int main(int argc, char** argv) {
	// Lettura dai file dati
	FILE* f_out = fopen("output.txt", "wt");
	FILE* f_bin = fopen("elena.bin", "rb");
	FILE* f_txt = fopen("marta.txt", "rt");
	nodo_albero* t = NULL;

	// Lettura e creazione dell'albero
	t = funzioneA(f_bin, f_txt, NULL);
	// Stampa a video
	funzioneB(t);
	// Stampa su file
	funzioneC(t, f_out);

	// Chiusura degli handles
	fclose(f_bin);
	fclose(f_txt);
	fclose(f_out);
	return 0;
}