001: #include<stdio.h>
002: #include<stdlib.h>
003: 
004: char menu(void);
005: void stampa(int *q, int size);
006: void salva(int *q, int size);
007: int *genera(int *size);
008: int *load(int *size);
009: 
010: int main(int argc, char **argv){
011: 
012:   int *q   = NULL;   // array che conterra' i quadrati generati o caricati da file
013:   int size = 0;      // dimensione riga o colonna
014:   // valori iniziali per quadrato vuoto...
015: 
016:   while(1)
017:   {
018:     char c = menu();
019:     switch(c)                         // chiamo la relativa procedura in accordo a quanto restituisce menu()
020:     {
021:       case 'l':
022:       case 'L':
023:   if(q)                        // devo liberare memoria 
024:     free(q);
025:   q = load(&size);
026:   break;
027:       case 'g':
028:       case 'G':
029:   if(q)       
030:     free(q);
031:   q = genera(&size);
032:   break;
033:       case 's':
034:       case 'S':
035:   salva(q, size);
036:   break;
037:       case 'p':
038:       case 'P':
039:   stampa(q, size);
040:   break;
041:       case 'x':
042:       case 'X':
043:   exit(EXIT_SUCCESS);
044:       default:
045:   fprintf(stderr, "Errore, opzione [%c] sconosciuta\n", c);
046:   break;
047:     }
048:   }
049: 
050: 
051:   return 0;
052: }
053: 
054: char menu(void)
055: {
056:   char c;
057: 
058:   printf("\nG - generare un nuovo quadrato magico\nL - caricare da file\nS - salvare su file\nP - stampa\nX - esci\n");
059:   printf("inserisci la tua scelta : ");
060:   scanf(" %c", &c);
061:   return c;
062: }
063: 
064: int *genera(int *size)
065: {
066:   do
067:   {
068:   printf("Inserisci la dimensione del quadrato magico che vuoi generare (dispari): ");
069:   scanf("%d", size);
070:   } while(!((*size)%2) && (*size)<0); // se divisibile per 2 non e' dispari o negativo, ripeto la richiesta (a rigore le parentesi non servono ma cosi' e' piu' leggibile)
071: 
072:   int nelementi = (*size)*(*size); // numero elementi array monodimensionale
073:   
074:   int *q = calloc(nelementi, sizeof(int)); // inizialmente lo riempo con degli zeri
075: 
076:   int y = 0, x = (*size)/2;  // tramite x e y mi sposto nel quadrato inizialmente prima riga in posizione centrale
077:   int valore = 1;            // valore di partenza
078: 
079:   do
080:   {
081:     q[x+y* *size] = valore; // imposto cella
082:     ++valore;
083:     int oldx = x;
084:     int oldy = y;
085:     --x;
086:     --y;  // aggiorno coordinate
087:     if(x<0) x += *size; // eventualmente correggo
088:     if(y<0) y += *size;
089:     if( q[x+y* *size] ) // se la nuova cella e' gia' piena devo correggere
090:     {
091:       x = oldx;
092:       y = oldy + 1;
093:       if(y >= *size ) // anche qui devo correggere
094:   y = 0;
095:     }
096:     stampa(q, *size); // DEBUG
097:   }
098:   while(valore <= (*size) * (*size)); // esco quando ho scritto nxn valori ovvero (*size) * (*size)
099:   stampa(q, *size); // DEBUG
100:   return q;
101: }
102: 
103: void stampa(int *q, int size)
104: {
105:   int x, y , i;;
106:   if(!size)  // controllo comunque mi sia stato passato un quadrato sensato
107:   {
108:     printf("Quadrato vuoto!\n");
109:     return;
110:   }
111:   
112:   // ciclo per riga e colonna
113:   for(y=0; y<size; ++y)
114:   {
115:     for(i=0; i<size; ++i)
116:       printf("+-----");
117:     printf("+\n");
118:     for(x=0; x<size; ++x)
119:     {
120:       printf("|%4d ", q[x+y*size]);
121:     }
122:     printf("|\n");
123:   }
124:   for(i=0; i<size; ++i)
125:     printf("+-----");
126:   printf("+\n");
127: }
128: 
129: 
130: void salva(int *q, int size)
131: {
132:   char filename[200];
133:   printf("Nome del file in cui salvare: ");
134:   scanf(" %s", filename);
135: 
136:   FILE *f=fopen(filename, "wb");
137:   if(!f)
138:   {
139:     perror("");
140:     exit(EXIT_FAILURE);
141:   }
142: 
143:   fwrite(&size, sizeof(int), 1, f);
144:   fwrite(q, sizeof(int), size*size, f);
145: 
146:   fclose(f);
147: }
148: 
149: int *load(int *size)
150: {
151:   char filename[200];
152:   printf("Nome del file da cui caricare: ");
153:   scanf(" %s", filename);
154: 
155:   FILE *f=fopen(filename, "rb");
156:   if(!f)
157:   {
158:     perror("");
159:     exit(EXIT_FAILURE);
160:   }
161: 
162:   fread(size, sizeof(int), 1, f);
163:   printf("Il file contiene una matrice %d x %d\n", *size, *size);
164:   int *q = malloc(sizeof(int) *  (*size) * (*size));
165: 
166:   fread(q, sizeof(int), (*size) * (*size), f);
167: 
168:   fclose(f);
169: 
170:   return q;
171: }
172: 
173: