Ciao ragazzi!
ho bisogno che qualcuno mi aiuti prima che io vada a finire alla neuro!!!
allora di seguito vi posto il mio codice in c++.
L'algoritmo utilizzanto è quello di huffman ed il programma dovrebbe comprimere un file e poi decomprimerlo.
Badate bene a quello che mi succede se cerco di codificare un file testo....(intendiamoci parlo di file di poche righe che ho fatto girare in modo da poter controllare in tutto col debug)
succede che quando nel primo ciclo while di letture di 8 bit per volta io mi vado a leggere tutto il file la cosa procede bene...ma quando nella fase di decodifica vado a leggere il file codificato,in particolare l'header dove ho salvato per ogni carattere le corrispottiva sequenza,il while con la file.get(ch) mi si blocca quando incontra un '.' (46 in ascii)
la cosa proprio non la capisco! :berto:
cioè sono due cicli while identici che fanno la stessissima cosa ma uno dei due si blocca quando incontra un '.'
se qualcuno potesser dare un'occhiata....premetto,il codice non è ben scritto assolutamente,almeno dal punto di vista formale...ho inizato a lavorarci solo da un paio di giorni e diciamo anche abbastanza di getto...sicuramente ci saranno un sacco di cose inutili ed insomma...non è un bel codice,ma per ora mi interessa che funzioni!
Quello che vi posso assicurare che la codifica e la decodifica viene fatta bene,l'ho provata col debug carta e penna...ma non capisco proprio perchè mi si blocca alla fine quel while!!è identico al precedente...ormai ci perdo la testa!!!!
codice:
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <fstream>
#include <time.h>
#include <queue>
#include <math.h>
using namespace std;
string deco="";
map<char,string> codec;
map<char,string> ::iterator ptr2;
class NodoHuff {
private:
char value;
char key;
const NodoHuff *f_destro;
const NodoHuff * f_sinistro;
public:
NodoHuff(char a =0,char b=0){ value=a;key=b;f_destro=0;f_sinistro=0;}
NodoHuff(const NodoHuff *destro,const NodoHuff *sinistro)
{key=destro->key+sinistro->key;
f_destro=destro;f_sinistro=sinistro;}
bool operator>(const NodoHuff &a)const
{return key>a.key;}
void trovacodifica (string code ="") const
{
if(f_sinistro)
{
f_sinistro->trovacodifica(code+"0");
f_destro->trovacodifica(code+"1");
}
else
codec[value]=code;
;}
string decodifica (string ss,NodoHuff nodo_corrente,int n)
{
short i=0;
NodoHuff *ptr = new NodoHuff (nodo_corrente);
*ptr=nodo_corrente;
int j=0;
while(i!=ss.size()&&j<n)
{
if(ss[i]=='0')
if(ptr->f_sinistro!= 0)
{
*ptr=*(ptr->f_sinistro);
i++;
}
else
{
deco=deco+(ptr->value);
j++;
*ptr=nodo_corrente;
}
if(ss[i]=='1')
if(ptr->f_destro!=0)
{
*ptr=*(ptr->f_destro);
i++;
}
else
{
deco=deco+(ptr->value);
j++;
*ptr=nodo_corrente;
}
}
return deco;
}
};
string recupera_codice(char x1)
{
string value;
char mask=1,i=0;
unsigned char x=(unsigned char)x1;
while (i<8)
{
if((x%2)==1)
{
value ="1"+value;
mask=mask<<1;
}
else
{
value="0"+value;
}
x=x/2;
i++;
}
return value;
};
string calcola_binario (string ss)
{
char j,x=8-(ss.size()%8);
for(j=0;j<x;j++)
ss=ss+'0';
short i=1;
string code="";
char value =0;
while(i!=ss.size())
{
if (ss[i-1]=='1')
value=value+(char)pow(2.F,8-(i%8));
if((i%8)==0 && i!=1)
{
if(ss[i-1]=='1')
value=value+1;
code=code+value;
value=0;
}
i++;
}
code=code+value;
return code;
}
void main ()
{
int num_b=0;
string codice="",codice2="";
ifstream file,file2,recupero,lettura2;
ofstream compresso,decompresso;
char nome_file[30],nome_compresso[30];
cout <<"Inserire il nome del file da comprimere : ";
cin>>nome_file;
file.open(nome_file);
if(file.fail())
{
cout<<endl<<"Errore in apertura file "<<endl;
exit(1);
}
char ch;
map <char,int> freq;
map <char,int>::iterator ptr;
file.get(ch);
while (!file.eof())//memorizzo per ogni carattere la
frequenza in una mappa ed in questo ciclo tutto funziona
bene anche se ho dei ..
{
ptr=freq.find(ch);
if(ptr==freq.end())
freq[ch]=1;
else
freq[ch]++;
file.get(ch);
num_b++;
}
ptr=freq.find(EOF);
if(ptr!=freq.end())
freq.erase(ptr);
int i=0;
cout<<"Inserire il nome del nuovo file compresso : ";
cin>>nome_compresso;
compresso.open(nome_compresso);
if(compresso.fail())
{
cout<<endl<<"Errore in apertura file "<<endl;
exit(1);
}
priority_queue< NodoHuff, vector<NodoHuff>, greater<NodoHuff> > Que;
for (ptr=freq.begin();ptr!=freq.end();ptr++)//inserisco i nodi nella coda di priorità
{
i++;
NodoHuff(ptr->first,ptr->second);
Que.push(NodoHuff(ptr->first,ptr->second));
}
compresso<<(int)freq.size();
if(i==(int)freq.size())
cout<<"ooook!"<<endl;
i=0;
for (ptr=freq.begin();ptr!=freq.end();ptr++)
{
compresso<<ptr->first<<ptr->second;
cout<<ptr->first<<' '<<ptr->second<<endl;
i++;
}
if(i==(int)freq.size())
cout<<"ooook!"<<endl;
compresso<<" ";
//creo l'albero di huffmann
while (Que.size()>1)
{
NodoHuff *destro = new NodoHuff( Que.top());
Que.pop();
NodoHuff *sinistro = new NodoHuff (Que.top());
Que.pop();
Que.push(NodoHuff(destro,sinistro));
}
Que.top().trovacodifica();
file2.open(nome_file);
while (file2.get(ch))
{
ptr2=codec.find(ch);
codice=codice+ptr2->second;
}
codice = calcola_binario (codice);
compresso<<num_b<<codice;
compresso.close();
file.close();
/******************************************decompressione**********************************************/
map <char,int> freq2;
map <char,int>::iterator ptrfre;
recupero.open(nome_compresso);
if(recupero.fail())
{
cout<<endl<<"Errore in apertura file "<<endl;
exit(1);
}
char ch2;
int x,max,j=0;
recupero>>max;
recupero.get(ch2);
while (j<max)//memorizzo per ogni carattere la
frequenza in una mappa, stesso ciclo di prima stesse istruzioni
e si blocca se trova dei ....
{
recupero>>x;
freq2[ch2]=x;
recupero.get(ch2);
j++;
}
priority_queue< NodoHuff, vector<NodoHuff>, greater<NodoHuff> > Que2;
for (ptrfre=freq2.begin();ptrfre!=freq2.end();ptrfre++)//inserisco i nodi nella coda di priorità
{
NodoHuff(ptrfre->first,ptrfre->second);
Que2.push(NodoHuff(ptrfre->first,ptrfre->second));
}
while (Que2.size()>1)
{
NodoHuff *destro = new NodoHuff( Que2.top());
Que2.pop();
NodoHuff *sinistro = new NodoHuff (Que2.top());
Que2.pop();
Que2.push(NodoHuff(destro,sinistro));
}
NodoHuff *testa = new NodoHuff(Que2.top());
decompresso.open("decompresso.txt");
recupero>>num_b;
recupero.get(ch2);
while(!recupero.eof())
{
codice2=codice2+recupera_codice(ch2);
recupero.get(ch2);
}
decompresso<<Que2.top().decodifica(codice2,Que2.top(),num_b);
}