Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1

    [C++]Programma compressione dati

    Salve a tutti
    Io ho scritto un programma di compressione dati che utilizza l'agoritmo di huffman, il problema e che il programma funziona benissimo con i txt ma non con altri formati, vi spiego come avviene implementazione:
    Leggo il file lo inserisco in uno stream di dati leggo un byte alla volta e verifico le ricorrenze, poi utilizzo il metodo di huffman per dare ai caratteri più ricorrenti una codifica di pochi bit.
    La mia domanda è quando inserisco un file immagine nello stream sono sempre byte è posso trattarli come dei char?

  2. #2

    Re: [C++]Programma compressione dati

    Originariamente inviato da zeno3083
    La mia domanda è quando inserisco un file immagine nello stream sono sempre byte è posso trattarli come dei char?
    Certamente.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Allora non riesco a capireperchè non va con formati diversi dal txt.

  4. #4
    Come apri e leggi il file?
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    lo metto su uno stream di input per leggere, e uno di output per scrivere.

  6. #6
    Posta il codice.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Ti posto il programma di compressione

    codice:
    #include <iostream>
    
    #include <fstream>
    
    #include <string>
    
    #include <map>
    
    #include <vector>
    
    #include <queue>
    
    #include "TreeHuffman.h"
    
    
    
    
    
    
    
    int main (int argc, char * const argv[]) {
    
            char nomefile[30];
    
            char nomefilescrittura[30];  //nome del file
    
            ifstream lettura;
    
            ifstream lettura2;  //creo un oggetto ifstream(lettura dei dati da un file sequenziale)
    
            ofstream scrittura;
    
            ofstream structfile;
    
        
    
            map<const char, int > freqMap;  //map(chiave,valore)
    
            map<const char, int > ::iterator it; //iteratore map
    
            priority_queue< TreeHuffman, vector<TreeHuffman>, greater<TreeHuffman> > q;//coda di priorità(elemento,chiave,???)
    
            TreeHuffman *hNode;//nodo
    
    
    
            char ch;
    
        
    
            cout << " Inserisci il nome del File da comprimere.  \n";
    
            cin >> nomefile;
    
            lettura.open(nomefile);//inserisce il file nello stream
    
            cout << "Inserisci il nome del nuovo file compresso. \n";
    
            cin >> nomefilescrittura;
    
    
    
            if (lettura.fail()){  //verfica se c'è un errore nell'apertura del file
    
                    cout << "Errore nell'apertura del file \n";
    
                    exit(1);
    
            }
    
    
    
            lettura.get(ch);//legge un byte alla volta
    
            while( !lettura.eof()) {  //verifica se siamo alla fine del file
    
                    it = freqMap.find(ch);//cerca il carattere e restituisce iteratore
    
                    if (it == freqMap.end())//verifica che non siamo alla fine della mappa
    
                            freqMap[ch] = 1;
    
                    else
    
                            freqMap[ch]++;
    
                    lettura.get(ch);
    
            }
    
    
    
            it = freqMap.begin();
    
            structfile.open("map.dat");
    
            //copia i valore della map nella coda di priorità
    
            while(it != freqMap.end()){
    
                    hNode = new TreeHuffman(it->first, it->second);//inizializzo l'oggetto Nodo
    
                    q.push(*hNode);//prende il puntatore al nodo e lo inserisce nella coda di priorità cosi da creare una coda di alberi
    
                    it++;//va all'elemento successivo
    
            }
    
            /*Prendo gli alberi con frequenza minore li sommo e creo il nuovo albero
    
            lo inserisco di nuovo nella coda di priorità, prendo di nuovo i due alberi
    
            con frequenza minore li sommo di nuovo e procedo cosi fin quando non mi rimane
    
            un solo elemeto nella coda di priorità che è il puntatore all'albero di huffmann*/
    
            while ( q.size() > 1 ) {
    
                  TreeHuffman *left = new TreeHuffman( q.top() );
    
                  q.pop();
    
                  TreeHuffman *right = new TreeHuffman( q.top() );
    
                  q.pop();
    
                  q.push( TreeHuffman( left, right ) );
    
                  }
    
            /*Ora che l'albero è stato creato non mi resta che crearmi il mio file compresso*/
    
            lettura2.open(nomefile);
    
            lettura2.get(ch);
    
            scrittura.open(nomefilescrittura);
    
            *hNode=q.top();
    
    		char control=ch;
    
             while( !lettura2.eof()) {  //verifica se siamo alla fine del file
    
                   string codice=hNode->trovacodifica(ch);        
    
                   scrittura<<codice;
    
                   lettura2.get(ch);
    
                   }
    
    		it=freqMap.begin();
    
    		while(it!=freqMap.end()){
    
    			ch=it->first;
    
    			string codice=hNode->trovacodifica(ch);
    
    			structfile<<(int)ch<<'§'<<codice<<'§';
    
    			cout<<"carattere "<<(int)ch<<"codifica "<<codice<<endl;
    
    			it++;
    
    		}
    
    			
    
    		
    
    			   
    
             scrittura.close();
    
    return 0;
    
            
    
    }

    e qui quello di decompressione

    codice:
    #include <iostream>
    
    #include <fstream>
    
    #include <string>
    
    #include <map>
    
    #include <vector>
    
    #include <queue>
    
    #include "TreeHuffman.h"
    
    
    
    
    
    
    
    
    
    int main (int argc, char * const argv[]) {
    
            char nomefile[30];
    
            char nomefilescrittura[30];  //nome del file
    
            ifstream recupero;  //creo un oggetto ifstream(lettura dei dati da un file sequenziale)
    
            ifstream lettura;
    
            ofstream scrittura;
    
        
    
            map<const string, char > freqMap;  //map(chiave,valore)
    
            map<const string, char > ::iterator it; //iteratore map
    
            
    
            recupero.open("map.dat");
    
            
    
            cout << " Inserisci il nome del File da decomprimere.  \n";
    
            cin >> nomefile;
    
            cout << "Inserisci il nome del nuovo file compresso. \n";
    
            cin >> nomefilescrittura;
    
            lettura.open(nomefile);//inserisce il file nello stream
    
    		scrittura.open(nomefilescrittura);
    
            
    
            char ch;
    
            char x;
    
            string ch1="";
    
    		string x1="";
    
            //scrittura.open(nomefilescrittura);
    
            
    
            while( !recupero.eof()) {  //verifica se siamo alla fine del file
    
             	recupero.get(x);
    
    			while(x!='§'){
    
    				x1+=x;
    
    				recupero.get(x);
    
            	}
    
    			if(x1=="")
    
    				x1=x;
    
    			recupero.get(ch);
    
                while(ch!='§'){
    
                            ch1+=ch;
    
                            recupero.get(ch);
    
                }
    
    			if(ch1=="")
    
    				 ch1=ch;
    
    			int y=atoi(x1.c_str());
    
                freqMap[ch1]=(char)y;
    
    			ch1="";
    
    			x1="";			
    
            }
    
            lettura.get(ch);
    
    		x1=ch;
    
    		it=freqMap.begin();
    
            while(!lettura.eof()){
    
    			while(freqMap.find(x1)==freqMap.end()){
    
    				lettura.get(ch);
    
    				x1+=ch;
    
    			}
    
    			scrittura<<freqMap[x1];
    
    			lettura.get(ch);
    
    			x1=ch;
    
    		}
    
                   
    
             scrittura.close();
    
    return 0;
    
            
    
    }

  8. #8
    Nella parte di scrittura del file compresso prova a sostituire
    codice:
    scrittura<<codice;
    con
    codice:
    scrittura.put(codice);
    .
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Scusa non vorrei sbagliarmi ma ".put" mi permette di scrivere caratteri mentre "codice" è una stringa, potrei utilizzare ".write", però non capisco dove sta la differenza.

  10. #10
    Scusa, hai più che ragione. Tuttavia mi era venuto in mente che poteva darsi che lo stream di output, usando i metodi per l'output formattato, effettuasse qualche genere di traduzione di caratteri indesiderata. Forse il problema invece sta nello stream di input... :master:
    Amaro C++, il gusto pieno dell'undefined behavior.

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.