001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004:
005: #define MSIZE (60)
006: #define NCOPPIE (512)
007: #define NFILE "brisk.csv"
008: #define OFILE "descr.txt"
009: #define BFILE "descr.bin"
010:
011: // struct per gestire 2 coppie di coordinate
012: struct brisk
013: {
014: unsigned int r1, c1, r2, c2;
015: };
016:
017: // prototipi funzioni utilizzate e definite dopo la main()
018:
019: struct brisk *leggi_csv(void);
020: void leggi_dati(char *, unsigned int [MSIZE][MSIZE]);
021: char *leggi_stringa(void);
022: void gen_descr(struct brisk *, unsigned int [MSIZE][MSIZE]);
023: void gen_descr_bin(struct brisk *, unsigned int [MSIZE][MSIZE]);
024:
025: int main(int argc, char **argv){
026:
027: // #1 chiamo funzione che esegue punto 1
028: struct brisk *coppie = leggi_csv();
029:
030: // #2
031: // chiedo nome file (ma poteva esser fatto internamente alla funzione successiva, e' una questione di stile)
032: printf("Inserisci nome file input: ");
033: char *nomefile = leggi_stringa();
034: // una funzione non puo' restituire array e
035: // di conseguenza lo devo passare io alla funzione
036: unsigned int mat[MSIZE][MSIZE];
037: // invoco funzione che legge da file e riempie array
038: leggi_dati(nomefile, mat);
039: free(nomefile);
040:
041: // #3
042: // chiedo nome file
043: // invoco funzione che calcola descrittore e lo salva su file
044: gen_descr(coppie, mat);
045:
046: // #BONUS, anche se non richiesto dal testo vi lascio da studiare questa funzione che
047: // genera effettivamente un reale descrittore binario e lo salva su file
048: gen_descr_bin(coppie, mat);
049:
050: // libero memoria prima di uscire
051: free(coppie);
052: return 0;
053: }
054:
055: // #1 leggo e memorizzo in struttura allocata dinamicamente il file brisk.csv
056: struct brisk *leggi_csv(void)
057: {
058: struct brisk *coppie = malloc(NCOPPIE*sizeof(struct brisk));
059:
060: FILE *f = fopen(NFILE, "r");
061: if(!f)
062: {
063: perror("");
064: exit(EXIT_FAILURE);
065: }
066: for(int i = 0; i < NCOPPIE; ++i)
067: {
068:
069: fscanf(f, "%u,%u,%u,%u", &coppie[i].r1, &coppie[i].c1, &coppie[i].r2, &coppie[i].c2);
070: printf("%u,%u,%u,%u\n", coppie[i].r1, coppie[i].c1, coppie[i].r2, coppie[i].c2);
071: }
072: fclose(f);
073:
074: // stampa di DEBUG (commentata dopo aver verificato il corretto funzionamento)
075: /*
076: printf("Ho letto:\n");
077: for(int i = 0; i < NCOPPIE; ++i)
078: printf("(%u,%u) (%u,%u)\n", coppie[i].r1, coppie[i].c1, coppie[i].r2, coppie[i].c2);
079: */
080:
081: return coppie;
082: }
083:
084: // #2 leggo e memorizzo in array bidimensionale
085: void leggi_dati(char *nfile, unsigned int m[MSIZE][MSIZE])
086: {
087: FILE *f = fopen(nfile, "r");
088: if(!f)
089: {
090: perror("");
091: exit(EXIT_FAILURE);
092: }
093:
094: // lettura da file ASCII
095: // leggo un valore per volta
096: // e lo sistemo nella relativa posizione
097: // riga per riga
098: for(int i = 0; i < MSIZE; ++i)
099: for(int j = 0; j < MSIZE; ++j)
100: fscanf(f, "%u", &m[i][j]);
101:
102: fclose(f);
103:
104: // stampa di DEBUG (commentata una volta verificato il funzionamento)
105: /*
106: for(int i = 0; i < MSIZE; ++i)
107: {
108: for(int j = 0; j < MSIZE; ++j)
109: {
110: printf("%3u ", m[i][j]);
111: }
112: printf("\n");
113: }
114: */
115: }
116:
117: // #3 genera descrittore e lo salva su file
118: void gen_descr(struct brisk *c, unsigned int mat[MSIZE][MSIZE])
119: {
120: unsigned char descr[NCOPPIE] = {0}; // array che contiene il descrittore, lo inizializzo a 0
121: for(int i = 0; i < NCOPPIE; ++i)
122: if(mat[c[i].r1][c[i].c1] > mat[c[i].r2][c[i].c2])
123: descr[i] = 1;
124:
125: FILE *fp = fopen(OFILE, "w");
126: if(!fp)
127: {
128: perror("");
129: exit(EXIT_FAILURE);
130: }
131:
132:
133: // stampa a schermo e salvataggio su file
134: printf("Descrittore: ");
135: for(int i = 0; i < NCOPPIE; ++i)
136: {
137: printf("%d", descr[i]);
138: fprintf(fp, "%d", descr[i]);
139: }
140: printf("\n");
141: fclose(fp);
142:
143:
144: }
145:
146: // #3 genera descrittore lavorando a livello di bit e lo salva su file
147: // come indicato sopra non era richiesto dal testo ma puo' essere
148: // utile esercizio di manipolazione bit
149: void gen_descr_bin(struct brisk *c, unsigned int mat[MSIZE][MSIZE])
150: {
151:
152: // come gestisco 512 bit? Un singolo int e' 4 byte ovvero 32 bit
153: // mi bastano 16 int per gestire quindi 512 bit
154: unsigned int descr[16] = {0};
155:
156: // per il singolo bit calcolato di volta in volta
157: unsigned int bit;
158:
159: // man mano che calcolo stampo anche
160: printf("Descrittore: ");
161:
162: // scandisco tutte le coppie
163: for(int i = 0; i < NCOPPIE; ++i)
164: {
165: // calcolo il relativo bit
166: if(mat[c[i].r1][c[i].c1] > mat[c[i].r2][c[i].c2])
167: bit = 1;
168: else
169: bit = 0;
170:
171: // man mano lo stampo a schermo
172: printf("%u", bit);
173:
174: // dove lo metto?
175: // il contatore del ciclo i lo posso vedere come indice del relativo bit che calcolo da 0 a 511
176: // in quale elemento di descr[] devo mettere quel bit lo posso calcolare dividendo i per 32 (numero di bit di ciascun elemento di decr[])
177: int index = i/32;
178:
179: // e quale bit uso di quell'elemento? In questo caso e' calcolabile come resto della divisione di i per 32
180: int offset = i%32;
181:
182: // la variabile bit contiene solo 1 o 0 quindi da un punto di vista binario sara'
183: // 00000000000000000000000000000000 oppure 00000000000000000000000000000001
184: // sposto il bit nella posizione in cui deve andare (scorrimento verso sinistra di offset)
185: // e per "iniettarlo" nel relativo elemento mi basta un or bit a bit '|'
186: descr[index] = descr[index] | (bit << offset);
187: }
188: printf("\n");
189:
190: // salvataggio su file binario
191: FILE *fp = fopen(BFILE, "w");
192: if(!fp)
193: {
194: perror("");
195: exit(EXIT_FAILURE);
196: }
197:
198: fwrite(descr, sizeof(unsigned int), 16, fp);
199:
200: fclose(fp);
201:
202:
203: }
204:
205:
206: // funzione di appoggio per lettura stringa
207: // vista identica a lezione
208: char *leggi_stringa(void)
209: {
210: char tmp[1000];
211: scanf(" %s", tmp);
212:
213: char *s = malloc(strlen(tmp) + 1);
214: strcpy(s, tmp);
215:
216: return s;
217: }
218: