// classificazione_prodotti.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// --- DEFINIZIONE ADT Mappa ---
typedef struct Nodo {
char *keyword;
char *categoria;
struct Nodo *next;
} Nodo;
typedef struct {
Nodo *testa;
} Mappa;
// --- FUNZIONI DI UTILITÀ ---
char *strdup_sicuro(const char *src) {
if (!src) return NULL;
return dest;
}
void to_lowercase(char *str) {
for (; *str
; ++str
) *str
= tolower(*str
); }
// --- INTERFACCIA ADT ---
Mappa *crea_mappa() {
Mappa
*mappa
= malloc(sizeof(Mappa
)); if (mappa) mappa->testa = NULL;
return mappa;
}
void distruggi_mappa(Mappa *mappa) {
if (!mappa) return;
Nodo *corr = mappa->testa;
while (corr) {
Nodo *temp = corr;
corr = corr->next;
}
}
void inserisci_mappa(Mappa *mappa, const char *keyword, const char *categoria) {
if (!mappa || !keyword || !categoria) return;
Nodo
*nodo
= malloc(sizeof(Nodo
)); if (!nodo) return;
nodo->keyword = strdup_sicuro(keyword);
nodo->categoria = strdup_sicuro(categoria);
if (!nodo->keyword || !nodo->categoria) {
return;
}
nodo->next = mappa->testa;
mappa->testa = nodo;
}
const char *trova_categoria(Mappa *dizionario, const char *prodotto) {
static char nome_copy[100];
strncpy(nome_copy
, prodotto
, sizeof(nome_copy
)); nome_copy[sizeof(nome_copy) - 1] = '\0';
to_lowercase(nome_copy);
Nodo *corr = dizionario->testa;
while (corr) {
if (strstr(nome_copy
, corr
->keyword
)) { return corr->categoria;
}
corr = corr->next;
}
return "Categoria sconosciuta";
}
void mostra_per_categoria(Mappa *prodotti, const char *categoria) {
Nodo *corr = prodotti->testa;
printf("Prodotti nella categoria '%s':\n", categoria
); while (corr) {
if (strcmp(corr
->categoria
, categoria
) == 0) { printf("- %s\n", corr
->keyword
); }
corr = corr->next;
}
}
void salva_mappa_su_file(Mappa *prodotti, const char *nomefile) {
FILE
*f
= fopen(nomefile
, "w"); if (!f) return;
Nodo *corr = prodotti->testa;
while (corr) {
fprintf(f
, "%s;%s\n", corr
->keyword
, corr
->categoria
); corr = corr->next;
}
}
void carica_mappa_da_file(Mappa *prodotti, const char *nomefile) {
FILE
*f
= fopen(nomefile
, "r"); if (!f) return;
char riga[256];
while (fgets(riga
, sizeof(riga
), f
)) { char *newline
= strchr(riga
, '\n'); if (newline) *newline = '\0';
char *sep
= strchr(riga
, ';'); if (sep) {
*sep = '\0';
inserisci_mappa(prodotti, riga, sep + 1);
}
}
}
void inizializza_dizionario_base(Mappa *dizionario) {
struct iniziale {
const char *keyword;
const char *categoria;
} diz[] = {
{"pasta", "Sfarinati"}, {"riso", "Sfarinati"},
{"farina", "Sfarinati"}, {"salame", "Salumeria/Macelleria"},
{"prosciutto", "Salumeria/Macelleria"}, {"pollo", "Salumeria/Macelleria"},
{"manzo", "Salumeria/Macelleria"}, {"formaggio", "Salumeria/Macelleria"},
{"carota", "Verdura/Frutta"}, {"cipolla", "Verdura/Frutta"},
{"mela", "Verdura/Frutta"}, {"banana", "Verdura/Frutta"},
{"acqua", "Bevande"}, {"birra", "Bevande"},
{"vino", "Bevande"}, {"aranciata", "Bevande"},
};
int n = sizeof(diz) / sizeof(diz[0]);
for (int i = 0; i < n; i++) {
inserisci_mappa(dizionario, diz[i].keyword, diz[i].categoria);
}
}
// --- MAIN ---
int main() {
Mappa *dizionario = crea_mappa();
Mappa *prodotti = crea_mappa();
inizializza_dizionario_base(dizionario);
carica_mappa_da_file(prodotti, "dati.txt");
char input[100];
int scelta;
while (1) {
printf("1. Classifica un prodotto\n"); printf("2. Mostra prodotti per categoria\n"); if (scanf("%d", &scelta
) != 1) break;
if (scelta == 1) {
printf("Inserisci il nome del prodotto: "); fgets(input
, sizeof(input
), stdin
); input
[strcspn(input
, "\n")] = '\0'; const char *categoria = trova_categoria(dizionario, input);
printf("Il prodotto \"%s\" appartiene al settore: %s\n", input
, categoria
); if (strcmp(categoria
, "Categoria sconosciuta") != 0) { inserisci_mappa(prodotti, input, categoria);
}
} else if (scelta == 2) {
printf("Inserisci il nome della categoria: "); fgets(input
, sizeof(input
), stdin
); input
[strcspn(input
, "\n")] = '\0'; mostra_per_categoria(prodotti, input);
} else if (scelta == 3) {
printf("Salvataggio e uscita...\n"); salva_mappa_su_file(prodotti, "dati.txt");
distruggi_mappa(dizionario);
distruggi_mappa(prodotti);
break;
} else {
printf("Scelta non valida.\n"); }
}
return 0;
}
Ly8gY2xhc3NpZmljYXppb25lX3Byb2RvdHRpLmMKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCi8vIC0tLSBERUZJTklaSU9ORSBBRFQgTWFwcGEgLS0tCnR5cGVkZWYgc3RydWN0IE5vZG8gewogICAgY2hhciAqa2V5d29yZDsKICAgIGNoYXIgKmNhdGVnb3JpYTsKICAgIHN0cnVjdCBOb2RvICpuZXh0Owp9IE5vZG87Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBOb2RvICp0ZXN0YTsKfSBNYXBwYTsKCi8vIC0tLSBGVU5aSU9OSSBESSBVVElMSVTDgCAtLS0KY2hhciAqc3RyZHVwX3NpY3Vybyhjb25zdCBjaGFyICpzcmMpIHsKICAgIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICAgIGNoYXIgKmRlc3QgPSBtYWxsb2Moc3RybGVuKHNyYykgKyAxKTsKICAgIGlmIChkZXN0KSBzdHJjcHkoZGVzdCwgc3JjKTsKICAgIHJldHVybiBkZXN0Owp9Cgp2b2lkIHRvX2xvd2VyY2FzZShjaGFyICpzdHIpIHsKICAgIGZvciAoOyAqc3RyOyArK3N0cikgKnN0ciA9IHRvbG93ZXIoKnN0cik7Cn0KCi8vIC0tLSBJTlRFUkZBQ0NJQSBBRFQgLS0tCk1hcHBhICpjcmVhX21hcHBhKCkgewogICAgTWFwcGEgKm1hcHBhID0gbWFsbG9jKHNpemVvZihNYXBwYSkpOwogICAgaWYgKG1hcHBhKSBtYXBwYS0+dGVzdGEgPSBOVUxMOwogICAgcmV0dXJuIG1hcHBhOwp9Cgp2b2lkIGRpc3RydWdnaV9tYXBwYShNYXBwYSAqbWFwcGEpIHsKICAgIGlmICghbWFwcGEpIHJldHVybjsKICAgIE5vZG8gKmNvcnIgPSBtYXBwYS0+dGVzdGE7CiAgICB3aGlsZSAoY29ycikgewogICAgICAgIE5vZG8gKnRlbXAgPSBjb3JyOwogICAgICAgIGNvcnIgPSBjb3JyLT5uZXh0OwogICAgICAgIGZyZWUodGVtcC0+a2V5d29yZCk7CiAgICAgICAgZnJlZSh0ZW1wLT5jYXRlZ29yaWEpOwogICAgICAgIGZyZWUodGVtcCk7CiAgICB9CiAgICBmcmVlKG1hcHBhKTsKfQoKdm9pZCBpbnNlcmlzY2lfbWFwcGEoTWFwcGEgKm1hcHBhLCBjb25zdCBjaGFyICprZXl3b3JkLCBjb25zdCBjaGFyICpjYXRlZ29yaWEpIHsKICAgIGlmICghbWFwcGEgfHwgIWtleXdvcmQgfHwgIWNhdGVnb3JpYSkgcmV0dXJuOwogICAgTm9kbyAqbm9kbyA9IG1hbGxvYyhzaXplb2YoTm9kbykpOwogICAgaWYgKCFub2RvKSByZXR1cm47CiAgICBub2RvLT5rZXl3b3JkID0gc3RyZHVwX3NpY3VybyhrZXl3b3JkKTsKICAgIG5vZG8tPmNhdGVnb3JpYSA9IHN0cmR1cF9zaWN1cm8oY2F0ZWdvcmlhKTsKICAgIGlmICghbm9kby0+a2V5d29yZCB8fCAhbm9kby0+Y2F0ZWdvcmlhKSB7CiAgICAgICAgZnJlZShub2RvLT5rZXl3b3JkKTsKICAgICAgICBmcmVlKG5vZG8tPmNhdGVnb3JpYSk7CiAgICAgICAgZnJlZShub2RvKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBub2RvLT5uZXh0ID0gbWFwcGEtPnRlc3RhOwogICAgbWFwcGEtPnRlc3RhID0gbm9kbzsKfQoKY29uc3QgY2hhciAqdHJvdmFfY2F0ZWdvcmlhKE1hcHBhICpkaXppb25hcmlvLCBjb25zdCBjaGFyICpwcm9kb3R0bykgewogICAgc3RhdGljIGNoYXIgbm9tZV9jb3B5WzEwMF07CiAgICBzdHJuY3B5KG5vbWVfY29weSwgcHJvZG90dG8sIHNpemVvZihub21lX2NvcHkpKTsKICAgIG5vbWVfY29weVtzaXplb2Yobm9tZV9jb3B5KSAtIDFdID0gJ1wwJzsKICAgIHRvX2xvd2VyY2FzZShub21lX2NvcHkpOwoKICAgIE5vZG8gKmNvcnIgPSBkaXppb25hcmlvLT50ZXN0YTsKICAgIHdoaWxlIChjb3JyKSB7CiAgICAgICAgaWYgKHN0cnN0cihub21lX2NvcHksIGNvcnItPmtleXdvcmQpKSB7CiAgICAgICAgICAgIHJldHVybiBjb3JyLT5jYXRlZ29yaWE7CiAgICAgICAgfQogICAgICAgIGNvcnIgPSBjb3JyLT5uZXh0OwogICAgfQogICAgcmV0dXJuICJDYXRlZ29yaWEgc2Nvbm9zY2l1dGEiOwp9Cgp2b2lkIG1vc3RyYV9wZXJfY2F0ZWdvcmlhKE1hcHBhICpwcm9kb3R0aSwgY29uc3QgY2hhciAqY2F0ZWdvcmlhKSB7CiAgICBOb2RvICpjb3JyID0gcHJvZG90dGktPnRlc3RhOwogICAgcHJpbnRmKCJQcm9kb3R0aSBuZWxsYSBjYXRlZ29yaWEgJyVzJzpcbiIsIGNhdGVnb3JpYSk7CiAgICB3aGlsZSAoY29ycikgewogICAgICAgIGlmIChzdHJjbXAoY29yci0+Y2F0ZWdvcmlhLCBjYXRlZ29yaWEpID09IDApIHsKICAgICAgICAgICAgcHJpbnRmKCItICVzXG4iLCBjb3JyLT5rZXl3b3JkKTsKICAgICAgICB9CiAgICAgICAgY29yciA9IGNvcnItPm5leHQ7CiAgICB9Cn0KCnZvaWQgc2FsdmFfbWFwcGFfc3VfZmlsZShNYXBwYSAqcHJvZG90dGksIGNvbnN0IGNoYXIgKm5vbWVmaWxlKSB7CiAgICBGSUxFICpmID0gZm9wZW4obm9tZWZpbGUsICJ3Iik7CiAgICBpZiAoIWYpIHJldHVybjsKICAgIE5vZG8gKmNvcnIgPSBwcm9kb3R0aS0+dGVzdGE7CiAgICB3aGlsZSAoY29ycikgewogICAgICAgIGZwcmludGYoZiwgIiVzOyVzXG4iLCBjb3JyLT5rZXl3b3JkLCBjb3JyLT5jYXRlZ29yaWEpOwogICAgICAgIGNvcnIgPSBjb3JyLT5uZXh0OwogICAgfQogICAgZmNsb3NlKGYpOwp9Cgp2b2lkIGNhcmljYV9tYXBwYV9kYV9maWxlKE1hcHBhICpwcm9kb3R0aSwgY29uc3QgY2hhciAqbm9tZWZpbGUpIHsKICAgIEZJTEUgKmYgPSBmb3Blbihub21lZmlsZSwgInIiKTsKICAgIGlmICghZikgcmV0dXJuOwogICAgY2hhciByaWdhWzI1Nl07CiAgICB3aGlsZSAoZmdldHMocmlnYSwgc2l6ZW9mKHJpZ2EpLCBmKSkgewogICAgICAgIGNoYXIgKm5ld2xpbmUgPSBzdHJjaHIocmlnYSwgJ1xuJyk7CiAgICAgICAgaWYgKG5ld2xpbmUpICpuZXdsaW5lID0gJ1wwJzsKICAgICAgICBjaGFyICpzZXAgPSBzdHJjaHIocmlnYSwgJzsnKTsKICAgICAgICBpZiAoc2VwKSB7CiAgICAgICAgICAgICpzZXAgPSAnXDAnOwogICAgICAgICAgICBpbnNlcmlzY2lfbWFwcGEocHJvZG90dGksIHJpZ2EsIHNlcCArIDEpOwogICAgICAgIH0KICAgIH0KICAgIGZjbG9zZShmKTsKfQoKdm9pZCBpbml6aWFsaXp6YV9kaXppb25hcmlvX2Jhc2UoTWFwcGEgKmRpemlvbmFyaW8pIHsKICAgIHN0cnVjdCBpbml6aWFsZSB7CiAgICAgICAgY29uc3QgY2hhciAqa2V5d29yZDsKICAgICAgICBjb25zdCBjaGFyICpjYXRlZ29yaWE7CiAgICB9IGRpeltdID0gewogICAgICAgIHsicGFzdGEiLCAiU2ZhcmluYXRpIn0sIHsicmlzbyIsICJTZmFyaW5hdGkifSwKICAgICAgICB7ImZhcmluYSIsICJTZmFyaW5hdGkifSwgeyJzYWxhbWUiLCAiU2FsdW1lcmlhL01hY2VsbGVyaWEifSwKICAgICAgICB7InByb3NjaXV0dG8iLCAiU2FsdW1lcmlhL01hY2VsbGVyaWEifSwgeyJwb2xsbyIsICJTYWx1bWVyaWEvTWFjZWxsZXJpYSJ9LAogICAgICAgIHsibWFuem8iLCAiU2FsdW1lcmlhL01hY2VsbGVyaWEifSwgeyJmb3JtYWdnaW8iLCAiU2FsdW1lcmlhL01hY2VsbGVyaWEifSwKICAgICAgICB7ImNhcm90YSIsICJWZXJkdXJhL0ZydXR0YSJ9LCB7ImNpcG9sbGEiLCAiVmVyZHVyYS9GcnV0dGEifSwKICAgICAgICB7Im1lbGEiLCAiVmVyZHVyYS9GcnV0dGEifSwgeyJiYW5hbmEiLCAiVmVyZHVyYS9GcnV0dGEifSwKICAgICAgICB7ImFjcXVhIiwgIkJldmFuZGUifSwgeyJiaXJyYSIsICJCZXZhbmRlIn0sCiAgICAgICAgeyJ2aW5vIiwgIkJldmFuZGUifSwgeyJhcmFuY2lhdGEiLCAiQmV2YW5kZSJ9LAogICAgfTsKICAgIGludCBuID0gc2l6ZW9mKGRpeikgLyBzaXplb2YoZGl6WzBdKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgaW5zZXJpc2NpX21hcHBhKGRpemlvbmFyaW8sIGRpeltpXS5rZXl3b3JkLCBkaXpbaV0uY2F0ZWdvcmlhKTsKICAgIH0KfQoKLy8gLS0tIE1BSU4gLS0tCmludCBtYWluKCkgewogICAgTWFwcGEgKmRpemlvbmFyaW8gPSBjcmVhX21hcHBhKCk7CiAgICBNYXBwYSAqcHJvZG90dGkgPSBjcmVhX21hcHBhKCk7CiAgICBpbml6aWFsaXp6YV9kaXppb25hcmlvX2Jhc2UoZGl6aW9uYXJpbyk7CiAgICBjYXJpY2FfbWFwcGFfZGFfZmlsZShwcm9kb3R0aSwgImRhdGkudHh0Iik7CgogICAgY2hhciBpbnB1dFsxMDBdOwogICAgaW50IHNjZWx0YTsKCiAgICB3aGlsZSAoMSkgewogICAgICAgIHByaW50ZigiXG4tLS0gTWVudSAtLS1cbiIpOwogICAgICAgIHByaW50ZigiMS4gQ2xhc3NpZmljYSB1biBwcm9kb3R0b1xuIik7CiAgICAgICAgcHJpbnRmKCIyLiBNb3N0cmEgcHJvZG90dGkgcGVyIGNhdGVnb3JpYVxuIik7CiAgICAgICAgcHJpbnRmKCIzLiBFc2NpXG4iKTsKICAgICAgICBwcmludGYoIlNjZWx0YTogIik7CiAgICAgICAgaWYgKHNjYW5mKCIlZCIsICZzY2VsdGEpICE9IDEpIGJyZWFrOwogICAgICAgIGdldGNoYXIoKTsgLy8gQ29uc3VtYSBuZXdsaW5lCgogICAgICAgIGlmIChzY2VsdGEgPT0gMSkgewogICAgICAgICAgICBwcmludGYoIkluc2VyaXNjaSBpbCBub21lIGRlbCBwcm9kb3R0bzogIik7CiAgICAgICAgICAgIGZnZXRzKGlucHV0LCBzaXplb2YoaW5wdXQpLCBzdGRpbik7CiAgICAgICAgICAgIGlucHV0W3N0cmNzcG4oaW5wdXQsICJcbiIpXSA9ICdcMCc7CiAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNhdGVnb3JpYSA9IHRyb3ZhX2NhdGVnb3JpYShkaXppb25hcmlvLCBpbnB1dCk7CiAgICAgICAgICAgIHByaW50ZigiSWwgcHJvZG90dG8gXCIlc1wiIGFwcGFydGllbmUgYWwgc2V0dG9yZTogJXNcbiIsIGlucHV0LCBjYXRlZ29yaWEpOwogICAgICAgICAgICBpZiAoc3RyY21wKGNhdGVnb3JpYSwgIkNhdGVnb3JpYSBzY29ub3NjaXV0YSIpICE9IDApIHsKICAgICAgICAgICAgICAgIGluc2VyaXNjaV9tYXBwYShwcm9kb3R0aSwgaW5wdXQsIGNhdGVnb3JpYSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHNjZWx0YSA9PSAyKSB7CiAgICAgICAgICAgIHByaW50ZigiSW5zZXJpc2NpIGlsIG5vbWUgZGVsbGEgY2F0ZWdvcmlhOiAiKTsKICAgICAgICAgICAgZmdldHMoaW5wdXQsIHNpemVvZihpbnB1dCksIHN0ZGluKTsKICAgICAgICAgICAgaW5wdXRbc3RyY3NwbihpbnB1dCwgIlxuIildID0gJ1wwJzsKICAgICAgICAgICAgbW9zdHJhX3Blcl9jYXRlZ29yaWEocHJvZG90dGksIGlucHV0KTsKICAgICAgICB9IGVsc2UgaWYgKHNjZWx0YSA9PSAzKSB7CiAgICAgICAgICAgIHByaW50ZigiU2FsdmF0YWdnaW8gZSB1c2NpdGEuLi5cbiIpOwogICAgICAgICAgICBzYWx2YV9tYXBwYV9zdV9maWxlKHByb2RvdHRpLCAiZGF0aS50eHQiKTsKICAgICAgICAgICAgZGlzdHJ1Z2dpX21hcHBhKGRpemlvbmFyaW8pOwogICAgICAgICAgICBkaXN0cnVnZ2lfbWFwcGEocHJvZG90dGkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmludGYoIlNjZWx0YSBub24gdmFsaWRhLlxuIik7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDA7Cn0K