PROBLEMA Esercizo in C sui File

giggio10

Nuovo Utente
20
0
Ciao a tutti, piacere sono un nuovo iscritto al forum :)
Vi volevo chiedere una mano su un problema riguardante i file in C.
La traccia del problema é: "Scrivi una funzione parametrica in grado di fondere due file di interi ordinati in senso crescente in un nuovo file, leggendo i tre nomi da input. Le eventuali ripetizioni devono essere eliminate. Quindi,visualizza sullo schermo i nuemri di valore maggiore in ordine decrescente."

La difficoltá che trovo sta nel fondere il contenuto dei due file.
Questo é quello che sono riuscito a fare:

#include <stdio.h>
#include <stdlib.h>
#define MAX 100


// PROTOTIPI DI FUNZIONE //
int lettura1(char file1[], int vett1[]);
int lettura2(char file2[], int vett2[]);
int lettura3(char file3[], int vett3[]);


int main () {
int scelta; // VARIABILI UTILIZZATA PER LO SWITCH //
char file1[MAX]; // VARIABILE DI TIPO CHAR, DOVE VA INSERITO IL NOME DEL PRIMO FILE //
char file2[MAX]; // VARIABILE DI TIPO CHAR, DOVE VA INSERITO IL NOME DEL SECONDO FILE //
char file3[MAX]; // VARIABILE DI TIPO CHAR, DOVE VA INSERITO IL NOME DEL SECONDO FILE //
// VETTORE CHE CONTERRA' TUTTI I NUMERI PRESENTI NEL FILE 1 //
// DIM1, VARIABILE CHE CONTIENE IL NUMERO TOTALE DI NUEMERI PRESENTI NEL FILE 1 //
// I, E' L'INDICE UTILIZZATO PER LA STAMPA DEL VETTORE 1 //
int v1[MAX], dim1, i;
// VETTORE CHE CONTERRA' TUTTI I NUMERI PRESENTI NEL FILE 2 //
// DIM2, VARIABILE CHE CONTIENE IL NUMERO TOTALE DI NUMERI PRESENTI NEL FILE 2 //
// J, E' L'INDICE UTILIZZATO PER LA STAMPA DEL VETTORE 2 //
int v2[MAX], dim2, j;
// VETTORE CHE CONTERRA' TUTTI I NUEMRI PRESENTI NEL FILE 3 //
// DIM3, VARIBILIE CHE CONTIENE IL NUMERO TOTALE DI NUMERI PRESENTI NEL FILE 3 //
// Z, E' L'INDICE UTILIZZATO PER LA STAMPA DEL VETTORE 3 //
int v3[MAX], dim3, z;


do { // INIZIO DEL CICLO DO - WHILE //
// COMANDO UTILIZZATO PER PULIRE LO SCHERMO, QUANDO IL MENU SI RIPETE //
system("cls");
printf("--------------------Menu--------------------");
printf("\n1- Leggi il primo e il secondo file.");
printf("\n2- Combina il primo e il secondo file, nel file 3.");
printf("\n3- Stampa del terzo file.");
printf("\n4- Esci dal programma.");
printf("\nQual'e' la tua scelta? ");
scanf ("%d", &scelta); // INSRIMENTO DI UN NUMERO NELLA VARIABILE SCELTA //


// INIZIO DELLA STRUTTURA SWITCH, CON IL CONTROLLO SULLA VARIABILE SCELTA //
switch(scelta) {
case 1: // CASO 1 //
printf("\nInserisci il nome del primo file: "); // INSERICI IL NOME DEL FILE CHE VUOI STAMPARE //
scanf("%s", file1); // AQUISIZIONE DEL NOME DEL FILE CHE SI VUOLE STAMPARE PER PRIMO //
dim1 = lettura1(file1, v1); // ASSEGANMO ALLA VARIABILE DIM1, IL VALORE RIPORATO DALLA FUNZIONE LETTURA1 //
printf("\nADESSO MI TROVO PRIMA DELLA STAMA DEL VETTORE 1.");
// INIZIO DEL CICLO PER LA STAMPA DEI NUMERI DEL VETTORE 1 //
for (i=0;i<dim1;i++) {
printf("\nADESSO SONO ALL'INTERNO DEL FOR DEL PRIMO VETTORE.");
printf("\n");
printf("%d ", v1);
printf("\nI=%d", i);
}


printf("\nInserisci il nome del secono file: "); // INSERICI IL NOME DEL FILE CHE VUOI STAMPARE //
scanf("%s", file2); // AQUISIZIONE DEL NOME DEL FILE CHE SI VUOLE STAMPARE PER SECONDO //
dim2 = lettura2(file2, v2); // ASSEGANMO ALLA VARIABILE DIM1, IL VALORE RIPORATO DALLA FUNZIONE LETTURA2 //
printf("\nADESSO MI TROVO PRIMA DELLA STAMA DEL VETTORE 2.");
// INIZIO DEL CICLO PER LA STAMPA DEI NUMERI DEL VETTORE 2 //
for (j=0;j<dim2;j++) {
printf("\nADESSO SONO ALL'INTERNO DEL CICLO FOR DEL SECONDO VETTORE.");
printf("\n");
printf("%d ", v2[j]);
}
printf("\n");
system("PAUSE");
break;
case 2: // CASO 2 //
j=0; // INIZIALIZZAZIONE DELLA VARIABILE J A 0 //
z=0; // INIZIALIZZAZIONE DELLA VARIABILE Z A 0 //
// INIZIO DEL FOR CHE CI PERMETTEREA DI INSERIRE I NUMERI IN ORDINE NEL VETTORE 3 //
for (i=0;i<dim1;i++) {
if (v1 != v2[j]) {
if (v1 > v2[j]) {
v3[z] =v1;
z++;
j++;
}
else {
v3[z] = v2[j];
z++;
j++;
}
}
}
FILE *tp; // INIZIALIZZAZIONE DI UN PUNTATORE A FILE //
printf("\nInserisi il nome del file dove deve essere salvare la fusione tra i primi due file: ");
scanf("%s" , file3);
tp = fopen(file3, "w");
for (z=0;z<dim3;z--) {
fprintf(tp, "%d ", file3);
}
fclose(tp);
printf("\n");
system("PAUSE");
break;
case 3:
dim3 = lettura3(file3, v3);
for (z=0;z<dim3;z++) {
printf("%d\t", v3[z]);
}
printf("\n");
system("PAUSE");
break;
case 4:
exit(1);
default:
printf("\nERRORE:il carattere inserito non e' valido.");
printf("\n");
system("PAUSE");
break;
}
} while(1);


return 0;
}


// DEFINIZIONE DI FUNZIONI //
int lettura1(char file1[], int vett1[]) {
int i=0;
FILE *fp1;
printf("\nSIAMO NELLA FUNZIONE DI LETTURA1.");
fp1 = fopen(file1, "r");
while (!eof(fp1)) {
printf("\nADESSO MI TROVO NEL CICLO WHILE DELLA FUNZIONE LETTURA1.");
fscanf(fp1, "%d ", &vett1);
i++;
}
fclose(fp1);
return i;
}


int lettura2(char file2[], int vett2[]) {
int j=0;
FILE *fp2;
printf("\nSIAMO NELLA FUNZIONE DI LETTURA2.");
fp2 = fopen(file2, "r");
while (!eof(fp2)) {
printf("\nADESSO MI TROVO NEL CICLO WHILE DELLA FUNZIONE LETTURA2.");
fscanf(fp2, "%d ", &vett2[j]);
j++;
}
fclose(fp2);
return j;
}


int lettura3(char file3[], int vett3[]) {
int k=0;
FILE *fp3;
printf("\nSIAMO NELLA FUNZIONE DI LETTURA3.");
fp3 = fopen(file3, "r");
while(!eof(fp3)) {
printf("\nADESSO MI TROVO NEL CICLO WHILE DELLA FUNZIONE LETTURA3.");
fscanf(fp3, "%d ", &vett3[k]);
}
fclose(fp3);
return k;
}

Grazie solo per il tempo perso per leggere tutto il codice :love:
 

DispatchCode

Utente Attivo
924
576
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
HDD
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
GPU
Nvidia Geforce GTX 960M, 4GB
Audio
Realtek
Net
30Mbps/3Mbps con Eolo
OS
Windows 10 64bit
Ho solo guardato così, e gli errori sembrano molti.

Ad esempio nel case 2, verso la fine, inizializzi Z a 0 ma la decrementi.

Risalendo il codice, l'errore è il for. Ammesso che così possa funzionare (con gli incrementi delle variabili nel ciclo, interni agli if intendo), non hai la certezza che sia realmente ordinato il terzo vettore. Non ne hai la certezza perchè se hai ad esempio:

{5, 2, 1, 6, 7, 9}
{3, 4, 6, 10, 2, 5}

v1[0] è maggiore di v2[0], quindi nel 3 avrai come primo elemento quello di v2 {3}.
Nella seconda iterazione v1[1] è minore di v2[1], quindi avrai come secondo elemento del terzo vettore {3,2}. Come noti non è già più ordinato.

Detto ciò, dipende da come sono formati i file anche. Scusa se sono stato un po' dispersivo, ma dato l'orario non connetto molto e non ho provato il source.

Detto ciò, imposterei in un altro modo il ciclo. Farei un while, con z che scorre sino a (dim1+dim2), ovvero la dimensione del terzo vettore. A questo punto non rimane che scorrere i vettori. Personalmente opterei per una soluzione semplice: scorri gli array ed inserisci i valori così come li trovi nel terzo vettore, e poi ordini il terzo vettore.
Se non fai in questo modo, dovrai scorrere continuamente i vettori per sapere quale valore è minore.

Immagina questa disposizione ad esempio:
{1,5,7,2,4}
{9,3,6,8,0}

In questo caso prendi il primo elemento di v1, poi il secondo di v2. Ma già qui ti rendi conto di due cose: la prima è che ti stai perdendo il valore 9 (il primo del secondo vettore); la seconda cosa è che hai nel terzo vettore {1,3} ma l'ultimo valore del secondo vettore è 0, che dovrebbe essere posizionato come primo elemento.
Ecco perchè un inserimento di tutti i valori nel terzo con riordinamento finale... pare, almeno al momento a quest'ora, la soluzione migliore. :P
 

giggio10

Nuovo Utente
20
0
Grazie, per avermi fatto notare gli errori adesso provo a riscrivere il ciclo come hai detto tu :D.
 

Sav_

Nuovo Utente
9
0
Mi accodo al commento di RootkitNeo e ti segnalo un paio di cose anche io:

-quando hai aperto il file, dopo aver usato la funzione fopen, io controllerei che il file è stato effettivamente aperto:

FILE *fp1;
fp1=fopen(file1, "r");

if(fp1 == NULL){
//Si è verificato un errore di apertura del file
}

Così quando esegui il programma ti rendi conto se il file viene aperto oppure no.

-Va bene l'utilizzo dei commenti, ma cerca di non abusarne. Se scrivi do{ .... è chiaro che inizia il ciclo do - while, non è necessario commentare e scrivere //Inizio ciclo do - while, oppure se scrivi case 2: è evidente che si tratti del caso 2 e non c'è bisogno di commentare.
L'idea del commento è quella di spiegare quello che stai facendo in quel pezzo di programma (o in quella riga), in modo che gli altri possano capirlo meglio oppure tu possa ricordartelo nel caso in cui dovessi riprendere il codice dopo un pò di tempo.

-Dopo aver letto i due file hai a disposizione due vettori che stando al testo dell'esercizio sono ordinati.
L'inserimento nel terzo vettore già in ordine decrescente credo che sia piuttosto macchinoso da effettuare, visto che bisognerebbe effettuare molti controlli e scorrere ogni volta entrambi i vettori. Quindi direi che come ti è stato già detto la soluzione migliore è quella di ordinare alla fine.
Ricordati che devi eliminare anche i duplicati, in questo caso io farei così: inserisco v1 in v3, inserisco i valori di v2 se questi non sono già presenti in v3. Considerando che i vettori potrebbero essere molto lunghi, scorrere alla fine tutto v3 per cercare se ci sono duplicati potrebbe essere molto oneroso.

 

giggio10

Nuovo Utente
20
0
Grazie a tutti per i consigli ma sono riuscito a risolvere.
Questo é il codice:


#include <stdio.h>
#include <stdlib.h>
#define MAX1 20
#define MAX2 100


int main () {
int scelta;
int app;
char file1[MAX1], file2[MAX1], file3[MAX1]; // VARIABILI UTILIZZATE PER IL NOME DEI FILE //
// VARIABILI UTILIZZATE PER IL FILE 1 //
int v1[MAX2], dim1, i;
FILE * fp1;
// VARIABILI UTILIZZATE PER IL FILE 2 //
int v2[MAX2], dim2, j;
FILE * fp2;
// VARIABILI UTILIZZARE PER IL FILE 3 //
int v3[MAX2],dim3, z, x, y, canc;
FILE * fp3;








do {
system("cls");
printf("\n--------------------MENU--------------------\n");
printf("\n1 - Leggi la traccia del problema.");
printf("\n2 - Lettura dei primi due file a video.");
printf("\n3 - Effettua l'elaborazione chiesta dalla traccia.");
printf("\n4 - Lettura del terzo file a video.");
printf("\n5 - Usicre da programma.");
printf("\n");
printf("\n---------- Qual' e' la tua scelta? ----------\n");
printf("\n--------------------> ");
scanf("%d", &scelta);


switch(scelta) {
case 1:
printf("\nScrivi una funzione parametrica in grado di fondere"
"due file di interi ordinati in senso crescente in un "
"nuovo file, leggendo i tre nomi da input."
"Le eventuali ripetizioni devono essere eliminate."
"Quindi, visualizza sullo schermo i 20 nuemri di "
"valore maggiore in ordine decrescente.");
printf("\n");
printf("\n----------CASO 1, COMPLETATO CON SUCCESSO.----------\n");
printf("\n");
system("PAUSE");
break;
case 2:
printf("\nInserisci il nome del primo file da aprire: ");
scanf("%s", file1);
fp1 = fopen(file1, "r");
if (fp1 == NULL) {
perror("Errore nell'apertura del file.");
exit(1);
}
// LETTURA DEL FILE 1 //
fscanf(fp1, "%d", &dim1);
for (i=0;i<dim1;i++) {
fscanf(fp1, "%d", &v1);
}
// STAMPA DEL CONTENUTO DEL FILE 1 //
printf("\nStampa del contenuto del file 1.\n");
for (i=0;i<dim1;i++) {
printf("%d\t", v1);
}
fclose(fp1);
printf("\n");
printf("\n--------------------LOADING--------------------\n");
printf("\nInserisci il nome del secondo file da aprire: ");
scanf("%s", file2);
fp2 = fopen(file2, "r");
if (fp2 == NULL) {
perror("Errore nell'apertura del file.");
exit(1);
}
// LETTURA FILE 2 //
fscanf(fp2, "%d", &dim2);
for(j=0;j<dim2;j++) {
fscanf(fp2, "%d", &v2[j]);
}
// STAMPA DEL CONTENUTO DEL FILE 2 //
printf("\nStampa del contenuto del file 2.\n");
for (j=0;j<dim2;j++) {
printf("%d\t", v2[j]);
}
fclose(fp2);
printf("\n");
printf("\n----------CASO 2, COMPLETATO CON SUCCESSO.----------\n");
printf("\n");
system("PAUSE");
break;
case 3:
z=0;
app=0;
// INSERIMENTO DEI NUMERI PRESENTI NEL PRIMO E SECONDO VETTORE, ALL'INTERNO DEL TERZO. //
for (i=dim1-1;i>=0;i--) {
v3[z] = v1;
z++;
}
for (j=dim2-1;j>=0;j--) {
v3[z] = v2[j];
z++;
}
// CALCOLO DELLA LUNGHEZZA DEL TERZO VETTORE //
dim3 = dim1 + dim2;
// ORDINAMENTO DEL TERZO VETTORE IN ORDINE DECRESCENTE //
for (x=0;x<dim3-1;x++) {
for(y=x+1;y<dim3;y++) {
if (v3[x] < v3[y]) {
app = v3[x];
v3[x] = v3[y];
v3[y] = app;
}
}
}


printf("\nInserisci il nome del terzo file da creare: ");
scanf("%s", file3);
fp3 = fopen(file3, "w");
// SCRITTURA IN UN FILE //
fscanf(fp3,"%d", dim3);
for (z=0;z<dim3;z++) {
fprintf(fp3, "%d", v3[z]);
}
fclose(fp3);
printf("\n");
printf("\n----------CASO 3, COMPLETATO CON SUCCESSO.----------\n");
printf("\n");
system("PAUSE");
break;
case 4:
printf("\nInserisci il nome del terzo file da aprire: ");
scanf("%s", file3);
fp3 = fopen(file3, "r");
if (fp3 == NULL) {
perror("\nErrore nell'apertura del file.");
exit(1);
}
// LETTURA DEL FILE 3 //
fscanf(fp3, "%d", &dim3);
for (z=0;z<dim3;z++) {
fscanf(fp3, "%d", &v3[z]);
}
// STAMPA DEL CONTENUTO DEL FILE 3 //
printf("\nStampa del contenuto del file 3.\n");
for (z=0;z<dim3;z++) {
printf("%d\t ", v3[z]);
}
fclose(fp3);
printf("\n");
printf("\n----------CASO 4, COMPLETATO CON SUCCESSO.----------\n");
printf("\n");
system("PAUSE");
break;
case 5:
exit(1);
default:
printf("\n\nERRORE: il carattere inserito non e' presente nelle scelte.");
printf("\n");
system("PAUSE");
break;
}
}while (1);




return 0;
}

FUNZIONA PERFETTAMENTE :party:
 

DispatchCode

Utente Attivo
924
576
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
HDD
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
GPU
Nvidia Geforce GTX 960M, 4GB
Audio
Realtek
Net
30Mbps/3Mbps con Eolo
OS
Windows 10 64bit
Potresti optare per un algoritmo più efficiente, ad esempio Insertion Sort (o altri ancora).
Codice:
for (x=0;x<dim3-1;x++) {
                for(y=x+1;y<dim3;y++) {
                    if (v3[x] < v3[y]) {
                        app = v3[x];
                        v3[x] = v3[y];
                        v3[y] = app;
                    }
                }
Piccola chicca: puoi effettuare lo scambio anche in questo modo
Codice:
for (x=0;x<dim3-1;x++) {
                for(y=x+1;y<dim3;y++) {
                    if (v3[x] < v3[y]) {
                        v3[x] ^= v3[y];
v3[y] ^= v3[x];
v3[x] ^= v3[y];
                    }
                }


Ultima cosa: la prossima volta che posti del codice, utilizza il tag BBCode CODE, così da facilitarne la lettura.
 

giggio10

Nuovo Utente
20
0
Ok penso proprio che inserirò la chicca che mi hai suggerito
Comunque si la prossima volta userò quel Tag
 

Entra

oppure Accedi utilizzando

Hot: PS5 VS XBOX X/S?

  • Playstation 5

    Voti: 453 63.6%
  • XBOX Series X/S

    Voti: 259 36.4%

Discussioni Simili