Kodowanie Huffmana, błąd w kodzie

0

Dzień dobry,

mam taki problem, że przez tą funkcję program mi się zawiesza:

/*			int licznik=0;
			wezel *tmp=head;
			while(licznik!=1)
			{
				licznik=0;
				while(tmp)
				{
					if(tmp->sumaCzest==0) licznik++;
					tmp=tmp->next;
				} 
				SymboleZastep(head);
			}
*/ 

W celu sprawdzenia co jest źle, skomentowałem ten fragment kodu i wywołałem tą funkcję kilkanaście razy. W przpypadku jeszcze jednego wywołania program się wykłada.

Prosiłbym o pomoc w znalezieniu błędu lub zwrócenia uwagi co robię nie tak. Cały kod poniżej. Dziękuję i pozdrawiam.


#include <iostream>
#include <fstream>
#include <string>

using namespace std;

ifstream wejscie;
ofstream wyjscie;

struct element		
{
	int kod;		// kod ascii
	int czestosc;	// czestosc pojawiania sie 
};

struct wezel		//wezel w liscie jednokierunkowej
{
	int symbolZast;
	int sumaCzest;
	wezel *left;
	wezel *right;
	wezel *up;
	wezel *next;
};

wezel *head=NULL;

int SymbolZastepczy=-1;

const int ilosc = 256;	// liczba elementów tablicy z modelem źródła
element model[ilosc];	// deklaracja tablicy przechowującej model źrółda

int testArgumentow(int argc, char *argv[]) // sprawdzenie poprawnosci argumentow
{
	if(argc==3)	
	{
	string funkcja = argv[1];
	string nazwaPliku = argv[2];
	if(funkcja == "\\K" || funkcja == "\\D" && !(nazwaPliku.empty()))
	{
	if(funkcja == "\\K") return 1;
	if(funkcja == "\\D") return 2;
	} 
	else
	{
	 	cout<<"Wprowadzono niepoprawne argumenty!"<<endl;
		cout<<"Pierwszy argument to \"\\K\" lub \"\\D\""<<endl;
		cout<<"Jesli kompresja danych to drugi argument to nazwapliku.rozszerzenie"<<endl;
		cout<<"Jesli dekompresja to drugi argument to nazwapliku.huffman\n"<<endl;
		
		return false;
	}
	}
	else
	{
	 	cout<<"Wprowadzono niepoprawne argumenty!"<<endl;
		cout<<"Pierwszy argument to \"\\K\" lub \"\\D\""<<endl;
		cout<<"Jesli kompresja danych to:"<<endl;
		cout<<"Drugi argument to nazwapliku.rozszerzenie"<<endl;
		cout<<"Jesli dekompresja to:"<<endl;
		cout<<"Drugi argument to nazwapliku.huffman\n"<<endl;
		
		return false;
	}
	
	return 0;
}

int sumaKontrolna(string nazwaPliku)
{
	cout<<"Obliczanie sumy kontrolnej..."<<endl;
	cout<<"CRC = "<<endl;
	return 0;
}

void modelZrodla(string nazwaPliku, element model[])
{
	string nazwa = nazwaPliku;
	cout<<"Rozpoczeto tworzenie modelu zrodla..."<<endl;
	
	char znak;	// odczytany znak
	int i = 0;
	
	for(i=0; i<256 ; i++)	// wypełnienie struktury kodami ascii
	{
		model[i].kod = i;
		model[i].czestosc = 0;
	}
	
	wejscie.open(nazwa.c_str(), ios::in); //otwarcie pliku
	while(wejscie.get(znak))	// odczytanie znaku z  pliku
	{
		model[(int)znak].czestosc += 1;	// konwersja na liczbę i zwiększenie czestosci
	}
	wejscie.close(); // zamknięcie pliku

	// wyswietlenie informacji o modelu
	int liczbaZnakow = 0;
	for(i=0 ; i<256 ; i++) liczbaZnakow+=model[i].czestosc;
	
	cout<<"\nWszystkich znakow w pliku = "<<liczbaZnakow<<endl;
	
	cout<<"\tKod ASCII\tCzestosc wystepowania"<<endl;
	for(i=0; i<256 ; i++)
	{
		if(model[i].czestosc!=0)	
		cout<<"\t"<<model[i].kod<<"\t\t\t"<<model[i].czestosc<<endl;
	}
	
}

void BubbleSort(element model[], int liczbaElementow) // sortowanie w kolejnosci rosnacej
{
		int k; 
		element tmp;
		do{
			k=0;
			
			for(int l=0 ; l<liczbaElementow-1 ; l++)
			if(model[l].czestosc>model[l+1].czestosc)
			{	
				tmp = model[l];
				model[l]=model[l+1];
				model[l+1]=tmp;
				k=1;
			}
		}while(k==1);
}

void add_on_end(wezel *&head, element model[], int i)	//funkcja dodająca węzeł na końcu listy
{
  	wezel *p, *new_node;

	new_node = new wezel;  
	new_node->next=NULL;   
 	new_node->sumaCzest=model[i].czestosc;
 	new_node->symbolZast=model[i].kod;
 	new_node->left=NULL;
 	new_node->right=NULL;
 	new_node->up=NULL;
 	
  	p = head;
 	
	if(p!=NULL)
	{
    	while(p->next!=NULL) p = p->next;
    	p->next = new_node;
  	}
  	else head = new_node;
}

void ListaLisci(element model[], int ilosc) //tworzenie listy lisci
											//posortowana wzgledem czestosci
{
	int i=0;
	while(model[i].czestosc==0) i++;
	
	while(i<ilosc)
	{
		add_on_end(head, model, i);
		i++;
	}
}

void SymboleZastep(wezel *&head)
{
	wezel *p=head;
	wezel *new_node;
	new_node = new wezel;
	
	while(p->sumaCzest==0) p=p->next;
	
	new_node->next=NULL;
	new_node->up=NULL;
	new_node->right=p;
	new_node->left=p->next;
	new_node->sumaCzest=(p->sumaCzest) + (p->next->sumaCzest);
	new_node->symbolZast=SymbolZastepczy;
	
	SymbolZastepczy--;
	
	p->up=new_node;
	p->next->up=new_node;
	p->sumaCzest=0;
	p->next->sumaCzest=0;
	
	p=head;
	
	while(p->next->sumaCzest<=new_node->sumaCzest) p=p->next;

	new_node->next=p->next;	
	p->next=new_node;
	
}

int main(int argc, char *argv[])
{
	int test = testArgumentow(argc,argv);
	if(test)
	{
		string nazwaPliku = argv[2];
		if(test==1) 
		{
			cout<<"Plik do kompresji: "<<nazwaPliku<<endl;
		
			wejscie.open(nazwaPliku.c_str(),ios::in);
			if(!wejscie.is_open())
			{
				cout<<"Plik nie istnieje."<<endl;
				return -1;
			}
			wejscie.close();
	
			sumaKontrolna(nazwaPliku);
						
			modelZrodla(nazwaPliku, model);
					
			BubbleSort(model, ilosc); // sortowanie w kolejnosci rosnacej
			
			ListaLisci(model, ilosc); // tworzenie listy lisci	
			
/*			int licznik=0;
			wezel *tmp=head;
			while(licznik!=1)
			{
				licznik=0;
				while(tmp)
				{
					if(tmp->sumaCzest==0) licznik++;
					tmp=tmp->next;
				} 
				SymboleZastep(head);
			}
*/			
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);										
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);										
			SymboleZastep(head);			
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);										
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);										
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);
			SymboleZastep(head);										
										

															
			for(;head;head=head->next)
			cout<<head->sumaCzest<<"\t"<<head->symbolZast<<endl;
		}
		else cout<<"Plik do dekompresji: "<<nazwaPliku<<endl;  
	

					
	}
	
	return 0;
}
 
1

Użyj debuggera...

0

nie za bardzo wiem w jaki sposób mam to zrobić, dla kodu gdzie argumenty podaje z konsoli

1

Używasz zapewne jakiegoś IDE? O ile tym IDE nie jest Dev-C++ (a jeśli jest, to zmień IDE), łatwo można w opcjach dodać parametry z którymi wywoływany jest program. Ostatecznie możesz też wczytywać parametry z stdin jeśli nie zostały podane.

Obsługa debuggera to bardzo przydatna umiejętność, często problemy z którymi byś walczył godzinę można rozwiązać parę minut debuggerem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1