Problema vettore struct e ordinamento da file .txt

di il
3 risposte

Problema vettore struct e ordinamento da file .txt

Lunedì ho un esame di fondamenti di informatica e mi stavo esercitando un po' con gli esami vecchi, quando trovo questo esercizio che propone l'ordinamento di un vettore a struct di n nazioni, da ordinare in base agli ori vinti, in caso di ori uguali confrontare gli argenti, e nel caso di argenti uguali confrontare i bronzi.
ho scritto il programma ma noto che c'è un problema con la lettura del file, probabilmente utilizzo male la funzione file.eof dato che rimane bloccato in quel loop.
Qualcuno saprebbe spiegarmi cosa sbaglio?

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

#define CARATTERI_MAX 10

struct nazione
{
char nome[CARATTERI_MAX + 1];
int ori;
int argenti;
int bronzi;
};


/* Restituisce il numero di righe contenute nel file “nomefile”. Si tenga
presente che ogni riga è strutturata come nell'esempio “medagliere.txt”. */
int contaRighe(const char* nomefile)
{
cout<<"Contatore righe"<<endl;
fstream file;
file.open(nomefile, ios::in);
int contatore=0;
int lunghezzaRiga=CARATTERI_MAX+10;
char* riga=new char [lunghezzaRiga];
while(file.getline(riga, lunghezzaRiga))
contatore++;
file.close();
delete[] riga;
return contatore;
}

/* Legge in input il file “nomefile” e popola il vettore “nazionali”, con il
nome, gli ori, gli argenti e i bronzi di ogni nazione. */
void leggiFile(nazione nazionali[], const char* nomefile)
{
fstream file;
int i=0;
file.open(nomefile, ios::in);
while(!file.eof())
{
file>>nazionali.nome>>nazionali.ori>>nazionali.argenti>>nazionali.bronzi;
i++;
}
file.close();
}

/* Ordina il vettore “nazionali” di lunghezza “n” in maniera decrescente
secondo i seguenti criteri:
– numero di ori
– a parità di ori, numero di argenti
– a parità di ori e argenti, numero di bronzi. */
void ordinaNazioni(nazione nazionali[], int n)
{
for(int j=0; j<n-1; j++)
{
for(int i=0; i<n-1; i++)
{
if(nazionali.ori<nazionali[i+1].ori)
{
nazione temp=nazionali;
nazionali=nazionali[i+1];
nazionali[i+1]=temp;
}
else
if(nazionali.ori==nazionali[i+1].ori)
{
if(nazionali.argenti<nazionali[i+1].argenti)
{
nazione temp=nazionali;
nazionali[i]=nazionali[i+1];
nazionali[i+1]=temp;
}
else
if(nazionali[i].argenti==nazionali[i+1].argenti)
{
if(nazionali[i].bronzi<nazionali[i+1].bronzi)
{
nazione temp=nazionali[i];
nazionali[i]=nazionali[i+1];
nazionali[i+1]=temp;
}
}
}
}
}
cout<<"Ordinati"<<endl;
}

/* Stampa a schermo il vettore “nazionali” di lunghezza n, come nell'esempio
di esecuzione. Ogni colonna ha l'intestazione “Ori”, “Argenti”, “Bronzi”,
come nell'esempio di esecuzione. */
void stampaMedagliere(nazione nazionali[], int n)
{
for(int i=0; i<n; i++)
{
cout<<setw(15)<<nazionali[i].nome<<setw(4)<<nazionali[i].ori<<setw(4)<<nazionali[i].argenti<<setw(4)<<nazionali[i].bronzi<<endl;
}
}

// Programma principale
int main()
{
const int n=contaRighe("palmares.txt");
nazione* nazionale = new nazione[n];
leggiFile(nazionale, "palmares.txt");
ordinaNazioni(nazionale, n);
stampaMedagliere(nazionale, n);
delete [] nazionale;
return 0;
}

3 Risposte

  • Re: Problema vettore struct e ordinamento da file .txt

    Usa i tag code per il codice o non si capisce
  • Re: Problema vettore struct e ordinamento da file .txt

    Dopo che hai messo il codice dentro al Tag code [</>] , lo trovi su "Editor completo & Anteprima"; si può vedere: medagliere.txt e/o palmares.txt?
    sono sufficienti alcune righe...
  • Re: Problema vettore struct e ordinamento da file .txt

    Il programma funziona non ci sono errori (esclusi quelli dovuti al non uso del Tag code) :
    
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    using namespace std;
    
    #define CARATTERI_MAX 10
    
    struct nazione
    {
        char nome[CARATTERI_MAX + 1];
        int ori;
        int argenti;
        int bronzi;
    };
    
    /* Restituisce il numero di righe contenute nel file “nomefile”. Si tenga
    presente che ogni riga è strutturata come nell'esempio “medagliere.txt”. */
    int contaRighe(const char* nomefile)
    {
        cout<<"Contatore righe: ";
        fstream file;
        file.open(nomefile, ios::in);
        int contatore=0;
        int lunghezzaRiga=CARATTERI_MAX+10;
        char* riga=new char [lunghezzaRiga];
        while(file.getline(riga, lunghezzaRiga))
        contatore++;
        file.close();
        delete[] riga;
        cout<<contatore<<endl;
        return contatore;
    }
    
    /* Legge in input il file “nomefile” e popola il vettore “nazionali”, con il
    nome, gli ori, gli argenti e i bronzi di ogni nazione. */
    void leggiFile(nazione nazionali[], const char* nomefile)
    {
        fstream file;
        int i=0;
        file.open(nomefile, ios::in);
    
        while(!file.eof())
        {
            file>>nazionali[i].nome>>nazionali[i].ori>>nazionali[i].argenti>>nazionali[i].bronzi;
            i++;
        }
        file.close();
    }
    
    /* Ordina il vettore “nazionali” di lunghezza “n” in maniera decrescente
    secondo i seguenti criteri:
    – numero di ori
    – a parità di ori, numero di argenti
    – a parità di ori e argenti, numero di bronzi. */
    void ordinaNazioni(nazione nazionali[], int n)
    {
        for(int j=0; j<n-1; j++)
        {
            for(int i=0; i<n-1; i++)
            {
                if(nazionali[i].ori<nazionali[i+1].ori)
                {
                    nazione temp=nazionali[i];
                    nazionali[i]=nazionali[i+1];
                    nazionali[i+1]=temp;
                }
                else
                if(nazionali[i].ori==nazionali[i+1].ori)
                {
                    if(nazionali[i].argenti<nazionali[i+1].argenti)
                    {
                        nazione temp=nazionali[i];
                        nazionali[i]=nazionali[i+1];
                        nazionali[i+1]=temp;
                    }
                    else
                    if(nazionali[i].argenti==nazionali[i+1].argenti)
                    {
                        if(nazionali[i].bronzi<nazionali[i+1].bronzi)
                        {
                            nazione temp=nazionali[i];
                            nazionali[i]=nazionali[i+1];
                            nazionali[i+1]=temp;
                        }
                    }
                }
            }
        }
        cout<<"Ordinati"<<endl;
    }
    
    /* Stampa a schermo il vettore “nazionali” di lunghezza n, come nell'esempio
    di esecuzione. Ogni colonna ha l'intestazione “Ori”, “Argenti”, “Bronzi”,
    come nell'esempio di esecuzione. */
    void stampaMedagliere(nazione nazionali[], int n)
    {
        for(int i=0; i<n; i++)
        {
            cout<<setw(15)<<nazionali[i].nome<<setw(4)<<nazionali[i].ori<<setw(4)<<nazionali[i].argenti<<setw(4)<<nazionali[i].bronzi<<endl;
        }
    }
    
    // Programma principale
    int main()
    {
        const int n=contaRighe("medagliere.txt");
        nazione* nazionale = new nazione[n];
        leggiFile(nazionale, "medagliere.txt");
        ordinaNazioni(nazionale, n);
        stampaMedagliere(nazionale, n);
        delete [] nazionale;
        return 0;
    }
    
    L'unico problema forse sta nel fatto che non metti il file medagliere.txt nel posto giusto, oppure hai il file medagliere.txt e poi tenti di leggere: palmares.txt

    Ho scritto il file: medagliere.txt, così
    
    Romania 4 9 16
    Italia 7 3 5
    Bulgaria 4 9 9
    Germania 6 3 18
    Brasile 4 9 2
    Francia 6 3 12
    Spagna 4 7 12
    
    e visto che nomefile non contiene il percorso, il file medagliere.txt l'ho copiato nella cartella del progetto.

    Output:
    
    Contatore righe: 7
    Ordinati
             Italia   7   3   5
           Germania   6   3  18
            Francia   6   3  12
            Romania   4   9  16
           Bulgaria   4   9   9
            Brasile   4   9   2
             Spagna   4   7  12
    
    Process returned 0 (0x0)   execution time : 0.028 s
    Press any key to continue.
    
Devi accedere o registrarti per scrivere nel forum
3 risposte