001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004: 
005: int check(char *); // prototipo funzione per punto 2.b
006: 
007: // struttura per punto 1
008: struct paese{
009:   int start; // inizio intervallo codice dello specifico paese/categoria
010:   int end;   // fine intervallo 
011:   char nome[86]; // nome paese/categoria
012: };
013: 
014: int main(int argc, char **argv){
015: 
016:   struct paese country[97]; // 97 righe note a tempo compilazione, inutile l'allocazione dinamica -> array statico
017: 
018: 
019:   // PUNTO 1 MEMORIZZAZIONE CONTENUTO countries.txt
020: 
021:   FILE *fp=fopen("countries.txt", "r");
022:   if(!fp){
023:     perror("Errore in apertura countries.txt");
024:     exit(1);
025:   }
026: 
027:   int riga=0;
028:   while(fscanf(fp, "%d", &country[riga].start)==1) // leggo il primo numero di ciascuna riga
029:   {
030:     char c=fgetc(fp);
031:     if(c=='-') // devo leggere un secondo numero
032:       fscanf(fp, "%d", &country[riga].end);
033:     else
034:       country[riga].end=country[riga].start; // altrimenti l'intervallo si riduce di fatto al primo numero e basta
035: 
036:     fscanf(fp, " %[^\n]", country[riga].nome);  // leggo il nome del paese/merce
037: 
038:     //printf("%3d %3d %s\n", country[riga].start, country[riga].end, country[riga].nome); //DEBUG
039:     ++riga;
040:   }
041:   fclose(fp);
042: 
043:   // PUNTO 2 lettura riga per riga di codici.txt
044:   char ean13[14];
045: 
046:   fp=fopen("codici.txt", "r");
047:   if(!fp){
048:     perror("Errore in apertura codici.txt");
049:     exit(1);
050:   }
051: 
052:   while(fscanf(fp, "%s", ean13) == 1) // leggo riga per riga
053:   {
054:     // PUNTO 1.a stampo
055:     printf("Codice letto: %s\n", ean13);
056: 
057:     // PUNTO 1.b invoco funzione per controllo
058:     int valido = check(ean13);
059: 
060:     // PUNTO 1.c stampo se valido o meno
061:     if(!valido)
062:     {
063:       printf("Checksum non valido, codice corrotto!\n\n");
064:       continue; // inutile procedere se il codice e' sbagliato
065:     }
066:     else
067:     {
068:       printf("Checksum valido, codice corretto\n");
069:     }
070: 
071:     // PUNTO 1.d cerco paese di provenienza e lo stampo
072:     int i;
073:     char codicepaese[4];
074:     strncpy(codicepaese, ean13, 3); // copio le prime tre lettere del codice in altra stringa
075:     int mycode = atoi(codicepaese);
076:     for(i=0; i<97; ++i)
077:     {
078:       if(mycode>=country[i].start && mycode<=country[i].end) // se ricade nell'intervallo ho trovato il paese
079:       {
080:   printf("Il codice %d corrisponde al paese %s\n\n", mycode, country[i].nome);
081:   break; // inutile continuare il ciclo
082:       }
083:     }
084:     // se arrivo in fondo al ciclo, il paese non l'ho trovato...
085:     if(i==97)
086:     {
087:   printf("Il codice %d non corrisponde a nessun paese elencato in countries.txt\n\n", mycode);
088:     }
089: 
090:   }
091:   fclose(fp);
092: 
093: 
094: 
095: 
096:   return 0;
097: }
098: 
099: int check(char *codice)
100: {
101:   int sumpari=0, sumdispari=0;
102: 
103:   int i;
104:   for(i=0; i<12; i=i+2) // ciclo sui pari 
105:   {
106:     sumpari    += codice[i]   - '0';  // con - '0' trasformo il codice ascii della cifra nel relativo valore
107:     sumdispari += codice[i+1] - '0';  // la cifra successiva e' dispari
108:   }
109: 
110:   int sum = sumpari + 3*sumdispari + (codice[13] - '0'); // sommo tutto incluso il checksum
111: 
112:   // se il codice e' corretto il risultato deve essere divisibile per 10
113:   sum = sum%10; // per risultati corretti -> 0
114: 
115:   return (sum?1:0);  // restituisco 1 o 0 a seconda che sum sia uguale o diversa da 0
116: }
117: