Ordinamento bubblesort file strutturati C++

di il
21 risposte

Ordinamento bubblesort file strutturati C++

Salve, ho un problema come da titolo. Praticamente si ha una struttura fatta di:
- char nome [30]
- int prezzo

Ciò che voglio fare io è inserire prima tutti i prodotti, e successivamente ordinarli alfabeticamente. Il mio programma, però, funziona solo a volte: ad esempio, non funziona con questa casuale combinazione nome-prezzo:
-Aouiop 9
-AAexd 5
-Aeofg 7
-Mopfr 5
-Bxd 3
-Bef 10

Vi posto il codice (la parte che dico io è la if(sc=='4'), le altre van bene). Secondo voi quale può essere il problema?

#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <fstream>
#include <cstring>
using namespace std;

struct tab{
    char nome[30];
    int prezzo;
}lista,aplista;

int main()
{
    char sc,sc2;
    FILE *f;
    cout<<"Scegli l'operazione da effettuare: \n";
    cout<<"1.Riscrittura lista\n";
    cout<<"2.Visualizzazione elenco\n";
    cout<<"3.Estrazione di un n-esimo record \n";
    cout<<"4.Ordinamento alfabetico\n";

    sc=getch();

    if(sc=='1'){//CREAZIONE E SCRITTURA
        f=fopen("lista.dat","w");

        do{
            cout<<"\nInserisci il nome dell'elemento: ";
            cin.getline(lista.nome,30);
            cout<<"Inserisci il suo prezzo: ";
            cin>>lista.prezzo;
            fwrite(&lista,sizeof(tab),1,f);

            cout<<"Vuoi inserire un altro prodotto? (s/n)\n";
            sc2=getch();
            fflush(stdin);
        }while(sc2=='s');

        fclose(f);
    }


    else if(sc=='2'&&fopen("lista.dat","r")){//SCANSIONE SEQUENZIALE
        f=fopen("lista.dat","r");
        fread(&lista,sizeof(tab),1,f);

        cout<<endl;
        while(!feof(f)){
            cout<<lista.nome<<"     "<<lista.prezzo<<endl;
            fread(&lista,sizeof(tab),1,f);
        }

        fclose(f);
    }

    else if(sc=='3'&&fopen("lista.dat","r")){//ESTRAZIONE
        int n;
        f=fopen("lista.dat","r");

        do{
            cout<<endl<<"Inserire il numero del prodotto (il primo e' 0): ";
            cin>>n;
            fseek(f,sizeof(tab)*n,SEEK_SET);

            if(fread(&lista,sizeof(tab),1,f)){
                cout<<endl<<lista.nome<<"     "<<lista.prezzo<<endl;
            }
            cout<<"\nVuoi cercare un altro prodotto? (s/n)\n";
            sc2=getch();
            fflush(stdin);
        }while(sc2=='s');
        fclose(f);
    }

    else if(sc=='4'&&fopen("lista.dat","r")){//ORDINAMENTO
        f=fopen("lista.dat","r+");
        int n=0,itemp;
        int s;
        char ctemp[30];

        do{
            s=0;
            n=0;
            fseek(f,sizeof(tab),SEEK_SET);

                                                        //Posizionamento sull'elemento immediatamente successivo e relativo controllo,
            while(fread(&lista,sizeof(tab),1,f)){       //equivale al for(i=0;i<n-1;i++)

                fseek(f,sizeof(tab)*n,SEEK_SET);
                fread(&lista,sizeof(tab),1,f);
                fseek(f,sizeof(tab)*(n+1),SEEK_SET);
                fread(&aplista,sizeof(tab),1,f);

                if(strcmp(lista.nome,aplista.nome)>0){  //Controllo alfabetico. E' maggiore di 0 se la prima stringa è più grande
                    strcpy(ctemp,lista.nome);
                    strcpy(lista.nome,aplista.nome);
                    strcpy(aplista.nome,ctemp);

                    itemp=lista.prezzo;
                    lista.prezzo=aplista.prezzo;
                    aplista.prezzo=itemp;

                    fseek(f,sizeof(tab)*n,SEEK_SET);
                    fwrite(&lista,sizeof(tab),1,f);

                    fseek(f,sizeof(tab)*(n+1),SEEK_SET);
                    fwrite(&aplista,sizeof(tab),1,f);

                    s=1;
                }

                n++;
                fseek(f,sizeof(tab)*(n+1),SEEK_SET);  //Funzione analoga a come visto sopra
            }
        }while(s==1);


        fclose(f);

    }

    system("pause");
    return 0;
}


21 Risposte

  • Re: Ordinamento bubblesort file strutturati C++

    Nessuno che possa aiutarmi?
  • Re: Ordinamento bubblesort file strutturati C++

    else if(sc=='4'&&fopen("lista.dat","r")){//ORDINAMENTO
            f=fopen("lista.dat","r+");
    Perché apri due volte il file?
  • Re: Ordinamento bubblesort file strutturati C++

    Perchè nell'if si controlla se si possa aprire il file genericamente, mentre dopo lo si apre tramite il puntatore *f.
  • Re: Ordinamento bubblesort file strutturati C++

    Ma no ... è un'assurdità ... ma dove le sentite queste cose? Chi ve le insegna?

    La fopen va eseguita una sola volta e controllata subito dopo. Elimina la fopen dalla if e controlla solamente il valore di f nel codice dopo la fopen
  • Re: Ordinamento bubblesort file strutturati C++

    Abbiamo iniziato i file ad accesso diretto da pochi giorni, ed essendo noi "in anticipo" col programma non ci sono sul libro, quindi usufruiamo di Internet dove c'è una confusione assurda.

    Ho corretto in questo modo, ma non va comunque:
    
    else if(sc=='4'){//ORDINAMENTO
            f=fopen("lista.dat","r+");
            if(!(f==NULL)){
            	fflush(stdin);
           		int n=0,itemp;
          		int s;
            	char ctemp[30];
    
            	do{
                	s=0;
                	n=0;
                    fseek(f,sizeof(tab),SEEK_SET);
    
                	while(fread(&lista,sizeof(tab),1,f)){       //equivale al for(i=0;i<n-1;i++)
    
                    	fseek(f,sizeof(tab)*n,SEEK_SET);
                    	fread(&lista,sizeof(tab),1,f);
                    	fseek(f,sizeof(tab)*(n+1),SEEK_SET);
                    	fread(&aplista,sizeof(tab),1,f);
    
                    	if(strcmp(lista.nome,aplista.nome)>0){  
                        	strcpy(ctemp,lista.nome);
                        	strcpy(lista.nome,aplista.nome);
                        	strcpy(aplista.nome,ctemp);
    
                        	itemp=lista.prezzo;
                        	lista.prezzo=aplista.prezzo;
                        	aplista.prezzo=itemp;
    
                        	fseek(f,sizeof(tab)*n,SEEK_SET);
                        	fwrite(&lista,sizeof(tab),1,f);
    
                        	fseek(f,sizeof(tab)*(n+1),SEEK_SET);
                        	fwrite(&aplista,sizeof(tab),1,f);
    
                        	s=1;
                    	}
    
                    	n++;
                    	fseek(f,sizeof(tab)*(n+1),SEEK_SET);  
                	}
            	}while(s==1);
    
    			fflush(stdin);
            	fclose(f);
    
        	}
        }
  • Re: Ordinamento bubblesort file strutturati C++

    Ovviamente non è la fopen il problema e neanche questa riga

    if(!f==NULL){

    che è sbagliata. Il problema è da qualche altra parte nell'ingarbugliato codice. Ma devi andare passo passo correggendo tutto quello che capita di incontrare.
  • Re: Ordinamento bubblesort file strutturati C++

    Boh, tipo qui usa il controllo
    
    if(fp==NULL){
         return;
    
    così da uscire se non lo apre, ed io ho fatto il contrario con la not, in modo da eseguire le operazioni solo se lo apre. A quanto pare è sbagliato
  • Re: Ordinamento bubblesort file strutturati C++

    Quindi devi scrivere

    if ( f != NULL )

    oppure semplicemente

    if ( f )
  • Re: Ordinamento bubblesort file strutturati C++

    Ah è a questo che ti riferivi. Bah, io non vedo dove sia l'errore, la mia dice "se non è vero che f è uguale a NULL", la tua dice "se f è diverso da NULL", il che è praticamente identico. L'unica cosa che avevo dimenticato erano le parentesi, ovvero if(!(f==NULL)).
    Poi ovvio che ognuno ha il suo stile, ma, francamente, l'argomento di questo topic non è il confronto dei vari stili di scrittura di ognuno di noi
  • Re: Ordinamento bubblesort file strutturati C++

    Non è solo una questione stilistica dimenticare delle parentesi.

    Anche se l'argomento del thread è diverso, deve essere segnalato ogni problema del codice, altrimenti questo non funzionerà mai ...

    Per valutare il codice velocemente, sarebbe utile che ci facessi scaricare uno zip con il progetto completo del codice e un file di dati riempito con i dati che vuoi ordinare.

    P.S. Tra l'altro, mi dispiace dirtelo, ma se ti rivolgi a qualcuno e ottieni un aiuto, dovresti farne tesoro e magari accennare ad un "grazie" piuttosto che replicare con boh e bah ...
  • Re: Ordinamento bubblesort file strutturati C++

    markolino1997 ha scritto:


    L'unica cosa che avevo dimenticato erano le parentesi, ovvero if(!(f==NULL)).
    Poi ovvio che ognuno ha il suo stile
    A parte il banale fatto che scrivere
    !f==NULL
    non e' la stessa cosa che scrivere
    !(f==NULL)
    lo stile, o la sua mancanza, dice molto della comprensione che uno ha della programmazione.

    Comunque, non esiste lo stile personale: per ogni linguaggio di programmazione ci sono delle regole di stile, nella stesura del codice, che devono essere seguite.

    Ovviamente ci sono tutta una serie di motivi sul perche' si debbano seguire queste regole, talmente ovvie che non serve nemmeno elencarle .
  • Re: Ordinamento bubblesort file strutturati C++

    oregon ha scritto:


    Se ti rivolgi a qualcuno e ottieni un aiuto, dovresti farne tesoro e magari accennare ad un "grazie" piuttosto che replicare con boh e bah ...
    Ma evidentemente hai frainteso. Io credevo che per te l'errore fosse nella not in sè, non nelle parentesi, e per questo mi sembrava strano. Ma comunque ti ringrazio per avermelo fatto notare, e allego subito il file.

    migliorabile ha scritto:


    lo stile, o la sua mancanza, dice molto della comprensione che uno ha della programmazione.
    Comunque, non esiste lo stile personale: per ogni linguaggio di programmazione ci sono delle regole di stile, nella stesura del codice, che devono essere seguite.
    Sinceramente non condivido affatto questo tuo pensiero, opinabile sotto molti punti di vista. Ogni programmatore ha un suo stile, e la prima cosa che insegnano è che un problema può essere risolto in vari modi, e vari algoritmi scritti differentemente (sia in sintassi che in semantica) infine risolvono lo stesso problema. Semmai è questo che dice molto sulla comprensione che uno ha della programmazione, e il mio uso della NOT fa puntualmente da esempio a questo, in quanto c'è seriamente gente che, scrivendo !=, ovvero "diverso", non si accorge che è una negazione di uguaglianza. E ancora posso parlarti di gente che usa goto, switch, break e continue, quando in realtà sono sconsigliati da molti, ma tecnicamente non sono scorretti.
    Oltretutto il mio messaggio di prima, ovvero quello in cui dicevo di non fermarci troppo su quest'argomento, era proprio per evitare di arrivare a discutere degli stili di programmazione.

    P.S. Questo forum non supporta file zip/rar come allegati, quindi l'ho uppato su EasyBytez
  • Re: Ordinamento bubblesort file strutturati C++

    Tutte quelle fseek non sono necessarie ... e probabilmente creano problemi.

    Dato che leggi/scrivi sempre due elementi del file, prevedi un vettore di due elementi da leggere/scrivere con una sola fread/fwrite e un elemento temporaneo per scambiare in un solo colpo la struttura, così
    
    struct tab{
        char nome[30];
        int prezzo;
    } elem[2], tmpt;
    
    A questo punto, il codice può calcolare con una sola fseek/ftell quanti sono i record da gestire e usare una comoda for se il numero di record è maggiore di 1 (altrimenti non c'è nulla da ordinare)
    
    			//ORDINAMENTO
    			f=fopen("lista.dat","r+");
    			fflush(stdin);
    
    			if(f)
    			{
    			   int n, s, i;
    			
    			   fseek(f, 0, SEEK_END);
    			   n=ftell(f)/sizeof(tab);
    
    				if(n>1)
    				{
            		 do
    					{
                		s=0;
                                         
                		for(i=0; i<n-1; i++)
    						{
                    	  fseek(f, sizeof(tab)*i, SEEK_SET);
                    	  fread(elem, sizeof(tab), 2, f);
    
    							if(strcmp(elem[0].nome, elem[1].nome)>0)
    							{
    								tmpt = elem[0];
    								elem[0] = elem[1];
    								elem[1] = tmpt;
    
                        	 fseek(f, sizeof(tab)*i, SEEK_SET);
                        	 fwrite(elem, sizeof(tab), 2, f);
    
                        	 s=1;
                    	  }
                	   }
            	   } while(s==1);
    
    				     fflush(stdin);
            			fclose(f);
        			}
    		}
    
  • Re: Ordinamento bubblesort file strutturati C++

    Grazie mille, ora funziona! Potresti però spiegarmi come funzionano le seguenti cose perfavore?

    -SEEK_END in fseek(f, 0, SEEK_END) (cosa cambia da SEEK_SET?)
    -n=ftell(f)/sizeof(tab); (anche se suppongo che prenda il numero di byte totali del file e li divida per la dimensione di ogni record, così da ottenere il numero dei record stessi)
Devi accedere o registrarti per scrivere nel forum
21 risposte