Informazione sull'utilizzo della dimensione dei vettori

di il
9 risposte

Informazione sull'utilizzo della dimensione dei vettori

Buonasera a tutti, di solidto quando programmo in c++ utilizzando i vettori faccio così:

int n;

cout<<"inserire la dimensione del vettore: ";
cin>>n;

int vet[n];

Bene finora tutto ok, ma con il passare del tempo, esercizio dopo esercizio e la voglia di progradire, di farmi venire idee di programmazione ho pensato ad una cosa che non saprei come risolvere (ammesso che si possa fare):

Come faccio a inserire un valore per dell'array per volta?

faccio un esempio:

voglio creare un array di 3 elementi.
int vet[3];
Dopo di chè chiedo: quanti quanti valori inserire nell'array?
Io voglio inserirne uno alla volta facendo così:

int n=1;

cout<<"Iserire un valore";
cin>>n;
char tasto=y;
cout<<"inserire un altro valore? ";
char y;
if(tasto==y){
cin>>n;
}

Ovviamente n essendo sempre uguale a 1, ottengo che invece che creare l'indice successiovo dell'array, va ovviamente a sovrascrivere il valore di prima, mentre se dopo incremento n di 1 accade che che devo inserire due valori, sovrascrivendo sempre il valore precedente. Come posso risolvere questo inconveniente?

9 Risposte

  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Per i vettori dinamici c'è std::vector (compila con la flag -std=c++11 o -std=c++14)

    Per l'input devi gestire gli errori sullo stream (cin.fail(), cin.clear(), cin.ignore()) e ci sono molte strade per farlo, ognuno ha la sua preferita

    Ci sono diversi esempi anche sul forum
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Weierstrass ha scritto:


    Per i vettori dinamici c'è std::vector (compila con la flag -std=c++11 o -std=c++14)

    Per l'input devi gestire gli errori sullo stream (cin.fail(), cin.clear(), cin.ignore()) e ci sono molte strade per farlo, ognuno ha la sua preferita

    Ci sono diversi esempi anche sul forum
    Grazie per l'informazione, ma posso usare questa std::vector anche senza la programmazione ad oggettI? Ad ora non vado oltre l'allocazione dinamica della memoria...
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Sì non hai bisogno delle classi

    Copio e incollo da thread recente
    
    #include <iostream>
    #include <vector> 
    
    using namespace std;
    
    void stampa(vector<int> l){
            for (auto it = l.begin(); it != l.end(); it++)
                cout << *it << " -> ";
            cout << "FINE" << endl;   
    } 
    
    int main (void) {
        vector<int> lista; 
        
        lista.push_back(10); stampa(lista);
        lista.push_back( 5); stampa(lista);
        lista.push_back( 3); stampa(lista);
        lista.push_back( 2); stampa(lista);
        lista.push_back( 1); stampa(lista);
        lista.push_back(42); stampa(lista);
        
        int start_address = 2;
        int stop_address  = 4;
        int somma, i;
        for(somma = 0, i = start_address; i <= stop_address; i++){
            somma += lista.at(start_address);
            lista.erase(lista.begin() + start_address);
        }
        lista.insert(lista.begin() + start_address, somma);
        stampa(lista);     
    
        return 0;
    }
    
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Weierstrass ha scritto:


    Sì non hai bisogno delle classi

    Copio e incollo da thread recente
    
    #include <iostream>
    #include <vector> 
    
    using namespace std;
    
    void stampa(vector<int> l){
            for (auto it = l.begin(); it != l.end(); it++)
                cout << *it << " -> ";
            cout << "FINE" << endl;   
    } 
    
    int main (void) {
        vector<int> lista; 
        
        lista.push_back(10); stampa(lista);
        lista.push_back( 5); stampa(lista);
        lista.push_back( 3); stampa(lista);
        lista.push_back( 2); stampa(lista);
        lista.push_back( 1); stampa(lista);
        lista.push_back(42); stampa(lista);
        
        int start_address = 2;
        int stop_address  = 4;
        int somma, i;
        for(somma = 0, i = start_address; i <= stop_address; i++){
            somma += lista.at(start_address);
            lista.erase(lista.begin() + start_address);
        }
        lista.insert(lista.begin() + start_address, somma);
        stampa(lista);     
    
        return 0;
    }
    
    Grazie per l'esempio, mi è stato molto utile per capire più o meno come funziona vector.

    Ma ora mi sono bloccato con la struct:
    
    struct prenotazione{
        char evento[50];
        int posti;
        
    };
    void input(vector<prenotazione>vettore, int valore);
    void stampa(vector<prenotazione>vettore, int valore);
    
    int main(int argc, char** argv) {
        int n=0;
        cout<<"dimensione: ";
        cin>>n;
        vector<prenotazione>v(n);
       
        input(v, n);
        stampa(v, n);
        
        
        return 0;
    }
    
    void input(vector<prenotazione>vettore, int valore) {
       for(int i=0; i<vettore.size(); i++){
            vettore.push_back(prenotazione[i].evento, prenotazione[i].posti);
        }
            
        
    }
    
    void stampa(vector<prenotazione>vettore, int valore){
        for(int i=0; i<vettore.size(); i++){
            cout<<"Nome evento: "<<vettore[i].evento<<endl;
            cout<<"Numero posti: "<<vettore[i].posti<<endl;
        }
    }
    
    Mi puoi aiutare a sviluppare le funzioni? Ovviamente quella della stampa non va bene poichè è quella degli array statici, stavo facendo un po di tentativi Per me è una cosa completamente che sono molto contento di apprendere e fortificare
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Se vuoi un esempio con le struct c'è questo dai vecchi thread
    
    #include <iostream>
    #include <algorithm>
    #include <vector> 
    
    using namespace std;
    
    struct immobile{
        char topologia;
        int  dimensione;
    };
    
    class myImmobile{
    
    public:
        void crea (){
          immobili.push_back({'A',32});
          immobili.push_back({'B',71});
          immobili.push_back({'C',12});
          immobili.push_back({'D',45});
          immobili.push_back({'E',26});
          immobili.push_back({'F',80});
          immobili.push_back({'G',53});
          immobili.push_back({'H',33});      
        }
        void ordinamento() {
            sort (immobili.begin(), immobili.end(), [ ] (immobile i, immobile j) { return i.dimensione < j.dimensione; });
        }
        void stampa(){
            for (auto it = immobili.begin(); it != immobili.end(); it++)
                cout << (*it).topologia << ' ' << (*it).dimensione << ' ';
            cout << endl;   
        } 
    private:
        vector<immobile>immobili; 
    };
    
    int main (void) {
        myImmobile test;
        
        test.crea();
        test.stampa();
        test.ordinamento();    
        test.stampa();    
    
        return 0;
    }
    
    
    C'è una classe e una lambda (funzione anonima [ ] dichiarata sul posto), ma niente di trascendente...
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Grazie per avermi postato questo esempio, ma non riesco ad inserire i dati in runtime.
    ad esempio se con i vettori statici l'imput funziona così
    
    void input(prenotazione vet[], int n){
    for(int i=0; i<n; i++){
    cout<<"evento"<<endl;
    cin>>v[i].evento;
    cout<<"posti";
    cin>>v[i].posti;
    }
    }
    
    come potrei fare per adattare questa funzione con push_back? Il CIN servirebbe ancora?
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    struct prenotazione{
        string evento;
        int posti;
    };
    
    int main()
    {
      vector<prenotazione> p;
      p.push_back({"prove",100});
      p.push_back({"prima",200});
      cout << "Evento : " << p.at(0).evento << " Posti : " << p.at(0).posti << endl;
      cout << "Evento : " << p[1].evento << " Posti : " << p[1].posti << endl;
      return 0;
    }
    
    Questo per l'output. Per l'input ti dichiari una variabile prenotazione p_in, poi fai cin sul membro p_in.evento e un altro cin sul membro p_in.posti, poi fai push_back(p_in)
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Weierstrass ha scritto:


    
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    struct prenotazione{
        string evento;
        int posti;
    };
    
    int main()
    {
      vector<prenotazione> p;
      p.push_back({"prove",100});
      p.push_back({"prima",200});
      cout << "Evento : " << p.at(0).evento << " Posti : " << p.at(0).posti << endl;
      cout << "Evento : " << p[1].evento << " Posti : " << p[1].posti << endl;
      return 0;
    }
    
    Questo per l'output. Per l'input ti dichiari una variabile prenotazione p_in, poi fai cin sul membro p_in.evento e un altro cin sul membro p_in.posti, poi fai push_back(p_in)
    
    struct prenotazione{
        string evento;
        int posti;
        
    };
     void input(vector<prenotazione>v, int n);
     void stampa(vector<prenotazione>v, int n);
    
    int main(int argc, char** argv) {
        int n;
        cout<<"dimensione: ";
        cin>>n;
        vector<prenotazione>v(n);
       
        input(v, n);
        stampa(v, n);
       
        
        
        return 0;
    }
    
    void input(vector<prenotazione>v, int n) {
         prenotazione p;
        for(int i=0; i<n; i++){
           cout<<"Inserire l'evento: "<<endl; 
           cin>>p.evento;
           cout<<"Inserire il numero di posti: "<<endl;
           cin>>p.posti;
           v.push_back(p);
           
        }
    }
    
    void stampa(vector<prenotazione>v, int n){
        prenotazione p;
        for(int i=0; i<n; i++){
            //cin.ignore();
            cout<<"Evento: "<<p.evento<<endl;
            cout<<"Posti: "<<p.posti<<endl;
           v.push_back(p);
        }
    }
    
    
    Questo è quello che sono riuscito a fare con tuoi suggerimenti, l'input funziona, ma la stampa no.
  • Re: Informazione sull'utilizzo della dimensione dei vettori

    Faccio notare che [CODE] int n; cin>>n; int vet[n]; non è codice standard C++ in quanto i VLA non sono supportati, ma probabilmente si tratta di una estensione del tuo compilatore.
    Quindi std::vector o std::unique_ptr<[]> (o new) sono le uniche alternative...

    Fai molta attenzione quando passi un std::vector, soprattutto in operazioni di input, in quanto deve essere passato per riferimento. [CODE] template <class T> // non reference void input(std::vector<T> v) { // copia su v, che però è un oggetto temporaneo std::copy(std::istream_iterator<T>(std::cin), std::istream_iterator<T>(), std::back_inserter(v)); // fine dello scope, v viene distrutta } template <class T> // reference void input_ref(std::vector<T> &v) { // copia su v, riferimento all'oggetto "v" del main std::copy(std::istream_iterator<T>(std::cin), std::istream_iterator<T>(), std::back_inserter(v)); } int main() { std::vector<int> v; input(v); // nessuna modifica a v input_ref(v); // v viene modificato } La corretta dichiarazione della tua funzione di input è quindi [CODE] void input(std::vector<prenotazione> &v, int n); Per la funzione di stampa suggerisco l'uso di un const std::vector<>& in modo da evitare la copia dell'oggetto, che di per sé non causa errori logici ma richiede una copia, ossia una perdita di tempo (e memoria).

    La cosa vale anche per gli std::array, le std::string e così via. Non si tratta di C array che vengono passati per riferimento in ogni caso.
Devi accedere o registrarti per scrivere nel forum
9 risposte