Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77

    [C++] Array da file di dimensioni ignote

    Ciao a tutti,
    ho un problema con un programma in cui devo prendere da tre file,tre array di dimensioni ignote e fare poi la media degli elementi contenuti in ciascun file e altre piccolezze che non sto qua a spiegare perchè so fare senza problemi. Il punto della questione è che facendo l'allocazione dinamica non so come scriverla poichè non posso inserire da tastiera la dimensione dell'array.

    codice:
    int n;
    int *vet;
    vet = new int[n]




    io penso che il problema stia proprio nella dichiarazione della dimensione dell'array,però se dichiaro un n molto grande andrei poi a creare caratteri spazzatura e chiaramente neanche credo vado bene come ho scritto sopra perchè sto dichiarando un array di dimensione n sconosciuta

  2. #2
    Se si tratta di fare solo media, deviazione standard e similari non è necessario tenere in memoria tutti i dati, puoi aggiornare i contatori man mano che leggi i dati senza salvarli. Se invece devi tenerli in memoria per statistiche più complicate usa un std::vector<int> e il relativo metodo push_back.

    Se non puoi usare std::vector (immagino per esigenze scolastiche) puoi o leggere tutti i dati senza salvarli e ma contandoli, allocare il vettore, fare il rewind del file e poi leggerli nel vettore.

    In alternativa, puoi fare come fa internamente il vector: tieni una "dimensione logica" del tuo array ("size", quanti elementi ci hai letto dentro) e una sua dimensione "fisica" ("capacity", quanto è grande il blocco di memoria allocato); parti allocando un buffer di una dimensione ragionevole (segnando quanto è grande nella capacity), e ogni volta che aggiungi un elemento incrementi la size. Quando la size raggiunge la capacity, fai una nuova allocazione grande il doppio, ci copi dentro gli elementi dal vecchio blocco di memoria, aggiorni la capacity e deallochi il blocco vecchio. Con questo sistema è garantito che asintoticamente non farai più di log(N) riallocazioni.
    Ultima modifica di MItaly; 09-02-2016 a 18:28
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77
    Per mia sfortuna hai ragione vector non lo abbiamo mai fatto inoltre il professore ha precisamente detto di utilizzare,per questo e tutti gli esercizi che ci capiteranno,l'allocazione dinamica che ti tratti di un array,matrice o altro. La questione è che il mio programma deve valere in tutte le condizioni possibili che conosca o meno la quantità di roba nel file quindi a questo punto senza poter inserire la dimensione da tastiera e fare l'allocazione dinamica c'è un altro modo per scriverla,altri soluzioni a parte questa purtroppo non posso utilizzare.

  4. #4
    Ti ho già dato ben due soluzioni che non richiedono std::vector...
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77
    Allora la prima credo che al prof non vada bene perchè lui pretende di salvare i dati in memoria,per quanto riguardo il secondo metodo l'idea già mi sembra più accettabile anche se devo dirti la verità non ho afferrato bene come dovrei procedere riguardo la scrittura dell'algoritmo

  6. #6
    Quote Originariamente inviata da Mrhide1 Visualizza il messaggio
    Allora la prima credo che al prof non vada bene perchè lui pretende di salvare i dati in memoria,
    E infatti alla fine i dati stanno in memoria... semplicemente leggi il file due volte, la prima volta leggi e scarti quello che leggi per contare gli elementi, poi allochi l'array della dimensione giusta, quindi fai rewind e questa volta leggi nell'array.
    per quanto riguardo il secondo metodo l'idea già mi sembra più accettabile anche se devo dirti la verità non ho afferrato bene come dovrei procedere riguardo la scrittura dell'algoritmo
    Cosa non ti è chiaro?
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77
    la cosa delle due dimensioni l'ho capita e anche il fatto che appena size diventa uguale a capacity faccio una nuova allocazione grande il doppio perchè chiaramente ci potrebbero essere dei casi di esaurimento della memoria, praticamente mi stai dicendo di creare per esempio un vettore dinamico di dimensione Size(esempio 10) e nel caso i dati nel file superino una certa dimensione Capacity (esempio 20) con un IF ( size > capacity) per dire, alloco un nuovo vettore dinamicamente con Capacity raddoppiata? e poi un'altra cosa che non ho capito quando dici "fai una nuova allocazione" intendi con lo stesso vettore che ho usato all'inizio o proprio un altro?

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77
    Ho provato a fare un programma penso simile a come dicevi tu MItaly,vedi se è giusto.
    In poche parole ho semplicemente predisposto un array dinamico di una certa lunghezza N,se poi nel file è presente un array di lunghezza minore tutto bene e lo stampa altrimenti entra nell'if e ti avvisa che il file è più grande della dimensione che hai inserito,a quel punto incrementa N finchè non diventa uguale a riemp e a quel punto stampa l'array

    codice:
    #include <iostream>#include <fstream>
    
    
    using namespace std;
    
    
    int main ()
    {
    	int n;
    	int *vet;
    	
    	cout << "inserisci la dimensione ";
    	cin >> n;
    	vet = new int [n];
    	
    	
    	fstream miofile;
    	miofile.open ("dati.txt",ios::in);
    	
    	int riemp = 0;
    	while (!miofile.eof())
    	{
    		miofile >> vet[riemp++];
    	}
    	
    	if (riemp>n)
    	{
    	cout << "attentione il file e' troppo grande\n\n";	
    	while (riemp>n)
    	{
    	  n = n + 1;	
    	}
    	cout << "la dimensione del file e': " << n << "\n\n";
    	for (int i=0;i<riemp; i++)
          cout << vet[i];
    	}
    	
    	
        else 
        {
          for (int i=0;i<riemp; i++)
          cout << vet[i];	
        }
    
    
      
    
    
    cout << "\n\n";
       system("pause");	
    }




  9. #9
    No, il gioco dovrebbe essere completamente automatico... una cosa di questo genere:
    codice:
    #include <iostream>
    #include <fstream>
    
    const int default_capacity = 16;
    
    int main() {
        std::ifstream miofile("dati.txt");
        if(!miofile) {
            std::cerr<<"Impossibile aprire il file\n";
            return 1;
        }
        // partiamo con size 0 (vettore vuoto) e una capacity qualunque 
        int size=0;
        int capacity=default_capacity;
        int *vec = new int[capacity];
        int r;
        while(miofile>>r) {
            // dobbiamo aggiungere un elemento 
            if(size>=capacity) {
                // vec è pieno; creiamo un nuovo array grande il doppio 
                capacity*=2;
                int *newvec = new int[capacity];
                // ci copiamo i vecchi elementi 
                for(int i=0; i<size; ++i) newvec[i]=vec[i];
                // buttiamo via il vecchio 
                delete[] vec;
                // e assegnamo a vec il puntatore al nuovo 
                vec = newvec;
            }
            // qui l'array puntato da vec è sicuramente grande a sufficienza
            // accoda il valore letto 
            vec[size]=r;
            // incrementa la dimensione logica 
            ++size;
        }
        // arrivati qui il file è stato letto completamente; fai quello che devi fare 
        std::cout<<"Letti "<<size<<" elementi dal file\n";
        for(int i=0; i<size; ++i) std::cout<<vec[i]<<"\n";
        // alla fine dealloca 
        delete[] vec;
        return 0;
    }
    Ultima modifica di MItaly; 10-02-2016 a 20:01
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2015
    Messaggi
    77
    Bellissimo il tuo programma, solo c'è una cosa che non ho capito tu dichiari quel Int r e poi il file lo metti in questo buffer perciò ora ti faccio una domanda un pò più tecnica,il fatto è che il mio file lo tengo sempre in mente come un vettore e l'idea di metterlo in una variabile intero che mi funge da buffer è una cosa che non comprendo a livello logico,cioè come fa un vettore in un file a essere messo in un intero e poi essere usato come lo hai usato tu ad esempio nella riga vec[size] = r. Comunque grazie per tutto l'aiuto che mi stai dando,se avessi un professore come te avrei preso già 30 e magari anche con la lode.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.