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: