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

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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
 

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

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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
Discord Ufficiale Entra ora!