Nicola156":1p9qgdlo ha detto:
non ci capisco più niente :matto) , e domani c'è l'orale....andiamo bene
temo concretamente che la tua preparazione sia un po'... carente...
ho cercato di usare un metodo "semplice", che potrebbe essere adatto ad un niubbo
---
dubito fortissimamenete di aver tempo di fare il secondo esercizio, sono alle prese con la sostituzione di un server
// convenzioni nomi parametri: i_xxx parametro di input; o_xxx parametro di i/output
// convenzioni costanti: D_ define; _G globale
#define D_G_MAX_LUNGHEZZA_NOME_SQUADRA 25 // max lunghezza nome di una squadra
#define D_G_MAX_NUMERO_SQUADRE 8 // max 8 squadre
#define D_G_MAX_LUNGHEZZA_NUMERO_SQUADRE 2 // fino a 2 caratteri per nr. squadra
#define D_G_MAX_LUNGHEZZA_LINEA 60 // max lunghezza di una riga file input
#include <stdio>
#include <stdlib>
struct squadra
{
char nomeSquadra[D_G_MAX_LUNGHEZZA_NOME_SQUADRA+1];
int codiceSquadra;
};
struct incontro
{
int codiceSquadra1;
int codiceSquadra2;
};
struct squadra squadreInput [D_G_MAX_NUMERO_SQUADRE+1];
struct incontro arrayScontri[D_G_MAX_NUMERO_SQUADRE / 2+1]; // gli scontri sono la metà delle squadre
// lettura file input; parametri handle lettura, puntatore squadre
// ritorna il numero di squadre lette (o zero in caso di errore)
int leggiFileInput(FILE* i_handleFile,struct squadra* o_squadre)
{
// la funzione riconosce righe contenenti caratteri non numerici
// esempio spazi prima del numero, possibile usare anche numeri più
// lunghi di un carattere
// esempi righe ammissibili
// 1 Juventus
// 2 Inter
// c3 Milan
// MANCA la gestione di righe vuote o non ben formattate
char linea[D_G_MAX_LUNGHEZZA_LINEA];
int i;
int indiceSquadraCorrente;
char numeroSquadraStringa[D_G_MAX_LUNGHEZZA_NUMERO_SQUADRE];
char backupCarattere;
char* inizioNumeroSquadra;
char* fineNumeroSquadra;
int codiceSquadraCorrente;
char* inizioNomeSquadra;
indiceSquadraCorrente=0;
if (i_handleFile)
while (!feof(i_handleFile))
{
if (fgets(linea,D_G_MAX_LUNGHEZZA_LINEA,i_handleFile))
{
i=0;
while(!isdigit(linea[i++]) && i<strlen(linea)); // saltiamo i caratteri non numerici
inizioNumeroSquadra=linea+i-1;
while (isdigit(linea[i++]) && i<strlen>D_G_MAX_NUMERO_SQUADRE)
{
printf("Errore di overflow:trovate troppe squadre nel file, max %d\r\n",D_G_MAX_NUMERO_SQUADRE);
system("PAUSE"); // per DOS. Nota non ci interessa chiudere il file
exit(0); // perchè lo fa il main in tutti i casi
}
}
}
return indiceSquadraCorrente;
}
// metodo per generazione incontri.
// ritorna zero in caso di errore, altrimenti gli incontri generati
int generaIncontri(struct squadra* i_squadre,int i_quanteSquadre,struct incontro* i_array)
{
int i;
int scontriOK;
int numeroRandom;
int arraySequenzaCasuale[D_G_MAX_NUMERO_SQUADRE+1];
int flagNumeroGiaPresente;
if ((i_quanteSquadre % 2) || (!i_quanteSquadre)) // controllo preliminare congruenza input
{
printf("generaAndata: Errore grave: i_quanteSquadre non >0 e pari\r\n");
return 0;
}
// inizializziamo il vettore arraySequenaCasuale a dati che sicuramente non possono
// corrispondere ad un codicesquadra. Sono flag di occupazione.
for (i=0;i<i_quanteSquadre;i++)
{
arraySequenzaCasuale
=D_G_MAX_NUMERO_SQUADRE+1000;
i_array.codiceSquadra1=D_G_MAX_NUMERO_SQUADRE+1000; // questo ci serve per situazioni di errore
i_array.codiceSquadra2=D_G_MAX_NUMERO_SQUADRE+1000; // (ovvero nel main), non strettamente necessari
}
srand(time(NULL)); // inizializza generatore numeri casuali
scontriOK=0;
while (scontriOK<i_quanteSquadre)
{
numeroRandom=rand() % i_quanteSquadre; // numero casuale tra 0 e numero squadre
flagNumeroGiaPresente=0; // flag: il numero è già stato generato (0=falso, 1=vero)
for (i=0;i<scontriOK;i++) // cerchiamo all'interno del vettore (scontriOK rappresenta
// la cardinalità dei numeri casuali "buoni" (non
// ripetuti)
if (arraySequenzaCasuale==numeroRandom) // se il numero è già nel vettore...
{
flagNumeroGiaPresente=1; // settiamo il flag
break; // ed usciamo dal ciclo
}
if (!flagNumeroGiaPresente) // a questo punto se il numero NON è presente...
// lo memorizziamo. Attenzione al "++" che
// incrementa il numero di scontri già generati
arraySequenzaCasuale[scontriOK++]=numeroRandom;
}
// per intercettare eventuali bug filliamo inizialmente il vettore con dati "assurdi"
// che ci permettano di capire se l'algoritmo lascia "buchi"
// esempio 1008 1008 1008 1008 1008 1008 1008 1008 significa che il vettore è vuoto
// generazione casuale numero 2
// 2 1008 1008 1008 1008 1008 1008 1008 il primo numero viene memorizzato
// generazione casuale numero 3
// 2 3 1008 1008 1008 1008 1008 1008 il secondo numero viene memorizzato
// generazione casuale numero 2
// 2 3 1008 1008 1008 1008 1008 1008 il terzo numero NON viene memorizzato
printf("Array casuale\r\n"); // scriviaamo a video
for (i=0;i<i_quanteSquadre;i++)
printf("%.2d ",arraySequenzaCasuale);
printf("\r\n");
for (i=0;i<i_quanteSquadre;i+=2) // memorizziamo. Attenzione che il numero degli
// scontri è pari alla META' delle squadre, e
// quindi c'è un "i+=2" che significa i=i+2
{
i_array[i/2].codiceSquadra1=arraySequenzaCasuale; // e qui dividiamo per due i
i_array[i/2].codiceSquadra2=arraySequenzaCasuale[i+1]; // (i è pari sicuramente, controllo iniziale)
}
return scontriOK/2; // ritorniamo il numero degli scontri
}
// questa funzione scrive su un file gli scontri, attingendo il nome dal parametro i_squadre
// se il primo parametro (i_flagInverti) è a zero scrive "andate", altrimenti "i ritorni"
// semplicemente inverte la stampa
void scrivi_output(int i_flagInverti,int i_quantiScontri,struct squadra* i_squadre,struct incontro* i_incontri,FILE* i_output)
{
int i;
// controlli vari sui parametri di input
if (!i_output)
{
printf("scrivi_output: errore grave, parametro file output vuoto\r\n");
return;
}
if (!i_quantiScontri)
{
printf("scrivi_output: errore grave, parametro quantiScontri a zero \r\n");
return;
}
if (!i_squadre)
{
printf("scrivi_output: errore grave, parametro squadre NULL\r\n");
return;
}
if (!i_incontri)
{
printf("scrivi_output: errore grave, parametro incontri NULL\r\n");
return;
}
// scrive due volte: una su video, una su file. La differenza tra le due versioni
// è semplicemente che scrive codiceSquadra1-codiceSquadra2 oppure codiceSquadra2-codiceSquadra1
for (i=0;i<i_quantiScontri;i++)
if (i_flagInverti)
{
printf("%25s - %25s\r\n",i_squadre[i_incontri.codiceSquadra1].nomeSquadra,i_squadre[i_incontri.codiceSquadra2].nomeSquadra);
fprintf(i_output,"%25s - %25s\r\n",i_squadre[i_incontri.codiceSquadra1].nomeSquadra,i_squadre[i_incontri.codiceSquadra2].nomeSquadra);
}
else
{
printf("%25s - %25s\r\n",i_squadre[i_incontri.codiceSquadra2].nomeSquadra,i_squadre[i_incontri.codiceSquadra1].nomeSquadra);
fprintf(i_output,"%25s - %25s\r\n",i_squadre[i_incontri.codiceSquadra1].nomeSquadra,i_squadre[i_incontri.codiceSquadra2].nomeSquadra);
}
}
int main(int argc, char *argv[])
{
FILE* handleInput;
FILE* handleOutput;
char nomeFileInput[250];
char nomeFileOutput[250];
int i;
int quanteSquadre;
int scontri;
if (argc!=3) // ci devono essere esattamente due parametri
{
printf("Parametri : nomefileinput nomefileoutput\n");
printf("Esempio : c:\\input.txt c:\\output.txt\n");
return 1;
}
// argv[0] è il nome del file eseguibile del programma
// argv[1] è il primo parametro (file di input)
// argv[2] è il secondo parametro (file di output)
sprintf(nomeFileInput ,"%s",argv[1]);
sprintf(nomeFileOutput ,"%s",argv[2]);
// copiamo argv[1] in nomeFileInput e argv[2] in nomeFileOutput perchè
// in fase di debug è oneroso mettere sempre i parametri a riga di comando:
// togliendo i commenti alle righe successive si impostano automaticamente
// i parametri
//sprintf(nomeFileInput,"%s","c:\\input.txt");
//sprintf(nomeFileOutput,"%s","c:\\output.txt");
printf("Apro file |%s|\r\n",nomeFileInput);
handleInput=fopen(nomeFileInput,"r"); // apro il file
if (handleInput) // controllo che sia effettivamente aperto
{
// leggo le squadre dal file di input e chiudo l'handle
quanteSquadre=leggiFileInput(handleInput,squadreInput);
// nota bene: il controllo successivo è ridondante, ma è possibile
// che la funzione leggiFileInput alteri lo stato del file e quindi,
// per buona abitudine, meglio mettere comunque il controllo di validità
// prima di chiuderlo.
// altra nnota: se leggiFileInput ritorna 0 siamo in situazione di errore
if (handleInput)
fclose(handleInput);
if (!quanteSquadre)
{
printf("main: errore in lettura squadre: abortisco\r\n");
return 1;
}
// adesso generiamo gli scontri
scontri=generaIncontri(squadreInput,quanteSquadre,arrayScontri);
printf("Squadre %.2d scontri %.2d OK\r\n",quanteSquadre,scontri);
// verifichiamo anche qui che non ci siano problemi (avrei scontri=0)
if (scontri)
{
handleOutput=fopen(nomeFileOutput,"w"); // apriamo il file in scrittura
if (handleOutput) // se OK
{
printf("File output aperto\r\n"); // stampiamo le squadre a video
for (i=0;i<quanteSquadre;i++)
printf("%.2d |%s|\r\n",squadreInput.codiceSquadra,squadreInput.nomeSquadra);
// doppie scritte (video + file), come richiesto dall'esercizio
printf("Quarti di finale 2006/2007\r\n");
fprintf(handleOutput,"Quarti di finale 2006/2007\r\n");
printf("Partite di andata\r\n");
fprintf(handleOutput,"Partite di andata\r\n");
// scriviamo l'andata. Attenzione al primo parametro di scrivi_output ZERO
scrivi_output(0,scontri,squadreInput,arrayScontri,handleOutput);
printf("Partite di ritorno\r\n");
fprintf(handleOutput,"Partite di ritorno\r\n");
// scriviamo l'andata. Attenzione al primo parametro di scrivi_output UNO
// che farà sì che la funzione inverta le squadre
scrivi_output(1,scontri,squadreInput,arrayScontri,handleOutput);
// chiudiamo il file, sempre con controllo aggiuntivo ridondante poichè
// abbiamo chiamato delle funzioni che, in teoria, avrebbero potuto
// chiudere il file "a tradimento"
if (handleOutput)
fclose(handleOutput);
}
else
{
// non siamo riusciti a scrivere sul file
printf("main: problema grave impossibile scrivere su file %s\r\n",nomeFileOutput);
if (handleInput) // nota test ridondante, ma è sempre bene metterlo
fclose(handleInput);
}
}
}
else
// non si è riusciti ad aprire il file di input
printf("main: problema grave impossibile aprire file %s\r\n",nomeFileInput);
system("PAUSE"); // per DOS
return 0; // se arriviamo fino a qui ritorniamo ZERO (tutto OK) alla shell
}