001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004:
005: // per semplicita' di lettura definisco costante per memorizzare numero comuni
006: #define NCOMUNI (7900)
007:
008: // PUNTO 1: definisco struct con dati singolo comune
009: struct comune
010: {
011: char *nome, provincia[3], codice[5];
012: };
013:
014: // prototipi funzioni definite dopo la main()
015: struct comune leggiriga(FILE *);
016: void stampacomuni(struct comune *);
017: void stampaprovincia(struct comune *, char *);
018: void ordinacomuni(struct comune *);
019:
020: int main(int argc, char **argv){
021:
022: // PUNTO 1: definisco array struct per memorizzare tutti i 7900 comuni
023: struct comune dati[NCOMUNI];
024:
025: FILE *fp;
026: fp = fopen("comuni.csv", "r");
027: if(!dati)
028: {
029: perror("");
030: exit(EXIT_FAILURE);
031: }
032:
033: //PUNTO 2: invoco funzione definita e riempo struttura dati
034: for(int i = 0; i < NCOMUNI; ++i)
035: {
036: dati[i] = leggiriga(fp);
037: // NOTA: il contenuto di una struct puo' essere copiato tranquillamente anche se
038: // contiene array all'interno
039: }
040:
041: // PUNTO 3: invocazione funzione stampacomuni()
042: //stampacomuni(dati);
043:
044: // PUNTO 4: invocazione di debug della funzione stampaprovincia()
045: stampaprovincia(dati, "BZ");
046:
047: // PUNTO 5: invocazione e stampa array ordinato
048: ordinacomuni(dati);
049: stampacomuni(dati);
050:
051:
052:
053: return 0;
054: }
055:
056: // PUNTO 2
057: struct comune leggiriga(FILE *input)
058: {
059: // temporanei per lettura dal file
060: char nome_tmp[1000];
061: char provincia_tmp[3];
062: char codice_tmp[5];
063:
064: // provo a leggere dal file, memorizzo quanto restituito dallla fscanf() per controllare se lettura e' andata a buon fine
065: int check = fscanf(input, " %[^;];%[^;];%s", nome_tmp, provincia_tmp, codice_tmp);
066: // come interpretare la stringa di formato (lo spazio iniziale e' per evitare che lo '\n' finisca nelle stringhe:
067: // 1. leggo primo elemento fino al primo ; escluso,
068: // 2. salto un ;,
069: // 3. leggo il secondo elemento fino al primo ; escluso,
070: // 4. salto un ;
071: // 5. leggo la terza stringa fino alla fine della linea
072:
073: // controllo di aver letto 3 elementi e in caso negativo esco
074: if(check != 3)
075: {
076: printf("ERRORE: non sono riuscito a leggere dal file...\n");
077: exit(EXIT_FAILURE);
078: }
079:
080:
081: // definisco struct da restituire
082: struct comune tmp;
083:
084: // sigla provincia e codice catasto posso tranquillamente copiarli in quanto lunghezza gia' definita
085: strcpy(tmp.provincia, provincia_tmp);
086: strcpy(tmp.codice, codice_tmp);
087:
088: // per nome comune prima devo allocare
089: tmp.nome = malloc(sizeof(char) * (strlen(nome_tmp) + 1));
090: // solo dopo posso copiare
091: strcpy(tmp.nome, nome_tmp);
092:
093: return tmp;
094: }
095:
096: // PUNTO 3
097: void stampacomuni(struct comune *a)
098: {
099: printf("ELENCO COMUNI:\n");
100: // banale ciclo di stampa
101: for(int i = 0; i < NCOMUNI; ++i)
102: printf(" %60s %s %s\n", a[i].nome, a[i].provincia, a[i].codice);
103:
104: }
105:
106: // PUNTO 4
107:
108: // funzione di appoggio necessaria per la qsort()
109: int confrontocomuni(const void *a, const void *b)
110: {
111: // converto tipo puntatori
112: const struct comune *primo = (const struct comune *)a;
113: const struct comune *secondo = (const struct comune *)b;
114:
115: // sfrutto e ritorno direttamente risultato strcmp()
116: return strcmp(primo->provincia, secondo->provincia);
117: }
118:
119: void stampaprovincia(struct comune *a, char *sigla)
120: {
121: printf("ELENCO COMUNI DELLA PROVINCIA ""%s"":\n", sigla);
122: // banale ciclo di stampa
123: for(int i = 0; i < NCOMUNI; ++i)
124: if(! strcmp(a[i].provincia, sigla) )
125: printf(" %60s %s %s\n", a[i].nome, a[i].provincia, a[i].codice);
126:
127: }
128:
129: // PUNTO 5
130: void ordinacomuni(struct comune *a)
131: {
132: qsort(a, NCOMUNI, sizeof(struct comune), confrontocomuni);
133: }
134: