codice:
/*
PROGRAMMA DI VERIFICA DELL'APPARTENENZA DI PUNTI, CONTENUTI IN UN FILE, A
CIRCONFERENZE IMMESSE DA TASTIERA.
-Questo programma opera sul file "punti a tromba.txt", che contiene numeri
considerati a 2 a 2 come coordinate di punti nel piano cartesiano. Viene
richiesto all'utente l'inserimento, da tastiera, di un certo numero di terne,
ciascuna delle quali rappresenta le coordinate del centro di una circonferenza
e l'area della stessa. A ciascuna circonferenza il programma assegna una lettera,
a partire dalla A e in ordine alfabetico. L'acquisizione si interrompe nel momento
in cui l'utente inserisce una terna il cui ultimo valore è minore o uguale a zero.
(Ovviamente, è comunque indispensabile porre un limite al numero di cerchi inseribili,
per motivi di memoria RAM)
-Dopo aver ultimato l'acquisizione, il programma indica se vi sono punti del file che si
trovano su qualche circonferenza immessa, scrivendo accanto a tali punti, nel file, le
lettere delle circonferenze di appartenenza.
*/
#include <stdio.h>
#include <stdio.h> //indispensabile per l'utilizzo delle funzioni I/O di base.
#include <math.h> //permette l'utilizzo della funzione che calcola la potenza di un numero.
#define PIG 3.142 //definisce una MACRO: la costante pi-greco.
#define N_MAX 30 //numero max di cerchi inseribili (secondo la logica di cui sopra).
struct punto //definisce la struttura punto, formata da 2 coordinate reali e un'ulteriore
{ //informazione, l'appartenenza a una circonferenza.
float x;
float y;
int app[N_MAX];
};
struct crf //definisce la struttura circonferenza, costituita da: coordinate del centro,
{ //area e nome.
float x;
float y;
float area;
char nome[2];
};
int acquisisci(struct crf*);
void nome(struct crf*,int);
int vedifile(FILE *,struct punto*);
void appart(struct crf*,int,struct punto*,int);
void riscrivi(struct punto*,int,FILE*);
void main()
{
int numc,nump; //dichiara 2 variabili deputate a contenere il numero dei cerchi e dei punti.
struct crf cerchi[N_MAX]; //dichiara un vettore di tipo struct crf di dimensione N_MAX.
struct punto file[10]; // " " " " " " punto " " 10.
FILE *fp; //dichiara un puntatore a file.
fp=fopen("punti a tromba.txt","r"); //il file source viene aperto in funzione read, l'indirizzo
//restituito dalla funzione fopen memorizzato in fp.
numc=acquisisci(cerchi);//chiamata della funz acquisisci:valore di ritorno memorizzato in numc.
nome(cerchi,numc); // " " " nome.
nump=vedifile(fp,file); // " " " vedifile: " " " " " nump.
appart(cerchi,numc,file,nump);
fclose(fp); //chiusura del file.
fp=fopen("punti a tromba.txt","w"); //riapertura dello stesso file in modalità write.
riscrivi(file,nump,fp);
fclose(fp); //richiusura del file.
printf("\nDai un'occhiata al file!\n(Sempre che esso contenesse punti appartenenti ad una circonferenza immessa)\n\n");
}
int acquisisci(struct crf*a) //funzione che passa per indirizzo il vettore dei cerchi e
{ //che restituisce un valore.
int flag=0,i=0; //i conta le crf, flag si attiva quando si inserisce un'area non positiva.
printf("Acquisizione dei cerchi: coordinate del centro e area\n(finisce se l'area e' nulla o negativa).\n\n");
do //ciclo che continua finchè le crf non superano
{ //il numero max permesso e le aree sono positive.
printf("Inserisci X e Y del centro e area (reali) del cerchio n%d:\n",i+1);
scanf("%f%f%f",&a[i].x,&a[i].y,&a[i].area); //acquisizione coordinate centro e area.
if(a[i].area<=0)
flag=1; //attivazione flag condizionata.
i++;
}
while(i<N_MAX&&flag==0);
return i-1;//restituisce il numero delle circonferenze (esclude l'ultima, che ha area non positiva).
}
void nome(struct crf* a,int b) //assegna il nome a ciascuna circonferenza; si poteva inserire
{ //direttamente nella "acquisisci" come mostrato alla fine del codice.
int i;
for(i=0;i<b;i++)
{
a[i].nome[0]='A'+i,a[i].nome[1]='\0';
}
}
int vedifile(FILE* c,struct punto*d)//passa per indirizzo il vettore dei punti e legge dal file.
{
int i=0;
while(fscanf(c,"%f%f",&d[i].x,&d[i].y)!=EOF) //memorizza i punti del file, li conta...
i++;
return i; //...e ne restituisce il numero.
}
void appart(struct crf*a,int b,struct punto* c,int d)
{//questa funzione passa per indirizzo i vettori dei cerchi e dei punti e per valore le loro dimensioni
int i,j,k; //per ogni punto, e per ogni cerchio, verifica se la distanza
for(j=0;j<d;j++) //punto-centro è uguale al raggio (calcolato a partire dall'area)
k=0;
for(i=0;i<b;i++) //PIG è double: dev'essere forzato a float.
{
if((pow((c[j].x-a[i].x),2)+pow((c[j].y-a[i].y),2))==a[i].area/(float)PIG)
{
c[j].app[k]=i;//uguaglia il campo "app" del dato strutturato punto al valore di i, che
k++;
} //equivale a 0 per la prima crf, 1 per la seconda ecc.
else
c[j].app[k]=-65;
}
}
void riscrivi(struct punto*a,int b,FILE* c) //riscrive su file.
{
int i,j=0; //riscrive su file i punti, nel modo più veloce (%g), seguiti dalle lettere
for(i=0;i<b;i++) //che corrispondono alle crf a cui appartengono (se ve ne sono): per app[j]=0
{ //ad esempio stamperà A. (0+65=0='A')
fprintf(c,"%g %g",a[i].x,a[i].y);
for(j=0;j<N_MAX;j++)
fprintf(c," %c",a[i].app[j]+65);
fprintf(c,"\n");
}
}