logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Kodowanie i dekodowanie metodą Huffmana - [język C w Dev cpp]

KRRySS 26 Maj 2011 16:33 3029 6
REKLAMA
  • #1 9546640
    KRRySS
    Poziom 2  
    Posty: 3
    Mam problem z kodowaniem Huffmana w języku C. Nie wiedzieć czemu program mi się sypie. Nie mogę znaleźć przyczyny. Ktoś ogarnięty w tym języku mógłby spojrzeć na to, ewentualnie wskazać te krytyczne miejsce. Z góry dziękuję wszystkim za pomoc.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    [/code]
  • REKLAMA
  • REKLAMA
  • #3 9547034
    KRRySS
    Poziom 2  
    Posty: 3
    Oczywiście od tego zacząłem. Problem właśnie w tym, że robiłem to pod Dev cpp(i w takiej formie muszę to oddać) i program się kompilował i nie wyrzucał żadnych błędów.
  • #4 9547247
    Zadusiciel
    Poziom 13  
    Posty: 61
    Pomógł: 9
    Ocena: 1
    Jak niepodasz parametrów do programu to argv[2] wychodzi poza zakres tablicy.
  • REKLAMA
  • #5 9547277
    lolcio
    Poziom 16  
    Posty: 133
    Pomógł: 29
    Ocena: 8
    Gdybyś używał komentarzy w programie to byłoby łatwiej znaleść błąd, pewnie sam byś go znalazł. Bez komentarzy bardzo cieżko czyta się jakiś dłuższy kod...a mogę się założyć że za poł roku nawet Ty nie będziesz pamietać co tu napisałeś a takto komentarze by Ci przypomniały.

    Ten program nie jest napisany zgodnie ze standardem C! Musisz sobie w dev-ie ustawić aby kompilował naprawde pod C, a nie C++. Tak powinien wyglądać ten program zgodnie z C:
    
    #include <stdlib.h>
    #include <stdio.h>
    
    #define bufsize 1024
    
    struct symbol
    
    {
    
           unsigned char znak;
    
           float czest;
    
    };
    
    
    
    struct znak
    
    {
    
           unsigned char symbol;
    
           unsigned char dlkodu;
    
           unsigned int kod;
    
    };
    
    
    
    int WyznaczCzestosci(char *nazwa, struct symbol *t)
    
    {
    
      FILE *plik;
    
      int n;
    
      int lwz=0;
    
      unsigned char buf[bufsize];
    
      plik=fopen(nazwa,"rb");
    
      if (!plik)
    
         {
    
                     printf("Nie mozna otworzyc pliku!");
    
                     return 1;
    
         } else
    
         {
    
               do
    
               {
    
                     n=fread(buf, sizeof(unsigned char), bufsize, plik);
    
    int i=0;
                     for ( ;i<n;i++)
    
                     (t+buf[i])->czest++;
    
                     lwz+=n;
    
               }while(n>0);
    
         fclose(plik);
    int k=0;
         for (;k<27;k++)
    
         (t+k)->czest/=(float)lwz;
    
         return 0;
    
         }
    
    }
    
    int porownaj(const void *op1,const void *op2)
    
    {
    
        const struct symbol *ptr1=(const struct symbol*)op1;
    
        const struct symbol *ptr2=(const struct symbol*)op2;
    
        if (ptr1->czest==ptr2->czest)
    
           return 0;
    
        else
    
        {
    
            if (ptr1->czest > ptr2->czest)
    
                return 1;
    
             else
    
                return -1;
    
        }
    
    }
    
    
    
    void wyswietl (struct symbol *t)
    
    {
    int i=0;
         for (; i<256; i++)
    
         printf("%c -> %f \n",(t+i)->znak,(t+i)->czest);
    
    }
    
    
    
    int ZapisDoPliku(char *nazwa, struct symbol *t)
    
    {
    
        FILE *plik;
    
        if(!(plik=fopen(nazwa,"wb")))
    
        {
    
                       printf("Nie mozna otworzyc pliku");
    
                       return 0;
    
        }   else
    
            {
    int i=0;
                for(; i<27; i++)
    
                {
    
         	      if(t->czest!=0)
    
                  fprintf(plik,"%c->%8.8f\n",t->znak,t->czest);
    
                }
    
          	fclose(plik);
    
           } return 1;
    
    }
    
    
    
    int UtworzTabliceKodowa(unsigned short *rozmiar, struct znak **t,char *sciezka)
    
    {
    
       FILE *plik2;
    
       if ((plik2=fopen(sciezka,"rb"))==NULL)
    
       {
    
          printf("Nie udalo sie otworzyc pliku");
    
          return 0;
    
       }
    
       else
    
       {
    
            fread(rozmiar, sizeof (unsigned short),1,plik2);
    
            *t=(struct znak *)calloc(*rozmiar,sizeof (struct znak));
    int i=0;
            for (;i<*rozmiar;i++)
    
            {
    
                     fread(&(*t+i)->symbol, sizeof(unsigned char),1,plik2);
    
                     fread(&(*t+i)->dlkodu, sizeof(unsigned char),1,plik2);
    
                     fread(&(*t+i)->kod,sizeof(unsigned int),1,plik2);
    
            }
    
    
    
            return 1;
    
       }
    
    }
    
    int Kompresuj (char *nazwaplikzr, char *nazwaplikwyn, struct znak **t, unsigned short rozmiar)
    
    {
    
        unsigned int tmp, paczka=0;
    
        int wolne=32;
    
        int dk;
    
        unsigned char litera;
    
        FILE *plikz;
    
        FILE *plikw;
    
        plikz=fopen(nazwaplikzr,"rb");
    
        plikw=fopen(nazwaplikwyn,"wb");
    
        paczka=0;
    
    
    
        while(fread(&litera,sizeof(unsigned char),1,plikz))
    
        {
    int i=0;
                                            for(;i<rozmiar;i++)
    
                                            {
    
                                                    if ((*t+i)->symbol == litera)
    
                                                    {
    
                                                                      tmp=(*t+i)->kod;
    
                                                                      dk=(*t+i)->dlkodu;
    
                                                                      break;
    
                                                    }
    
                                                    }
    
                                                    if(wolne>=dk)
    
                                                    {
    
                                                                 tmp<<=(wolne-dk);
    
                                                                 paczka^=tmp;
    
                                                                 wolne-=dk;
    
                                                                 if(wolne==0)
    
                                                                 {
    
                                                                             fwrite(&paczka,sizeof(unsigned int),1,plikw);
    
                                                                             paczka=0;
    
                                                                             wolne=32;
    
                                                                 }
    
                                                    }
    
                                                    else {
    
                                                         paczka^=(tmp>>(dk-wolne));
    
                                                         fwrite(&paczka,sizeof(unsigned int),1,plikw);
    
                                                         paczka=0;
    
                                                         tmp<<=32+wolne-dk;
    
                                                         paczka^=tmp;
    
                                                         wolne=32+wolne-dk;
    
                                                         }
    
       }
    
       if(paczka!=0){
    
         fwrite(&paczka,sizeof(unsigned int),1,plikw);}
    
       fclose(plikz);
    
       fclose(plikw);
    return 0;
    }
    
    
    
        int Dekompresuj(char *nazwaplikzr,char *nazwaplikwyn,struct znak *t){
    
    
    
         FILE *plikz,*plikw;
    
         unsigned int tmp, paczka1=0,paczka2=0;
    
    
         int wolne=32;
    
    
    
    
    
         if((plikz=fopen(nazwaplikzr,"rb"))==NULL){
    
                    printf("Brak pliku do zdekompresowania");
    
                    return 1;
    
                    }
    
    
    
         plikw=fopen(nazwaplikwyn,"w+");
    
         fread(&paczka1,sizeof(unsigned int),1,plikz);
    
         if(paczka1==0){
    
             printf("Plik pusty\n");
    
             return 1;
    
         };
    
         fread(&paczka2,sizeof(unsigned int),1,plikz);
    
    
    
         while(paczka1!=0){
    
                           int i=-1;
    
                             do{
    
                                i++;
    
                                tmp=paczka1;
    
                                tmp>>=32-(t+i)->dlkodu;
    
                                }
    
                             while (tmp!=(t+i)->kod);
    
    
    
                             fwrite(&(t+i)->symbol,sizeof(unsigned char),1,plikw);
    
                             paczka1<<=(t+i)->dlkodu;
    
                             if(wolne>=(t+i)->dlkodu){
    
                                 tmp=paczka2;
    
                                 wolne=wolne-(t+i)->dlkodu;
    
                                 tmp>>=32-(t+i)->dlkodu;
    
                                 paczka1|=tmp;
    
                                 paczka2<<=(t+i)->dlkodu;
    
                             }
    
                             else if((wolne<(t+i)->dlkodu)&&!feof(plikz)){
    
    
    
                                 tmp=paczka2;
    
                                 tmp>>=32-wolne;
    
                                 wolne=(t+i)->dlkodu-wolne;
    
                                 tmp<<=wolne;
    
                                 paczka1|=tmp;
    
                                 fread(&paczka2,sizeof(unsigned int),1,plikz);
    
                                 wolne=32-wolne;
    
                                 if(!feof(plikz)){
    
                                 tmp=paczka2;
    
                                 tmp>>=wolne;
    
                                 paczka1|=tmp;
    
                                 paczka2<<=32-wolne;
    
    
    
                                      }
    
                                 }
    
    
    
                             }
    
         fclose(plikz);
    
         fclose(plikw);
    
         return 0;
    
         }
    
    
    
    
    
    int main(int argc, char *argv[])
    
    {
    
        unsigned short rozmiar;
    
        struct znak *tabkod;
    
        struct symbol tab[256];
    
        WyznaczCzestosci(argv[2],tab);
    
        wyswietl(tab);
    
        UtworzTabliceKodowa(&rozmiar, &tabkod, argv[1]);
    
        if(*argv[4]==107)
    
        Kompresuj(argv[2], argv[3], &tabkod, rozmiar);
    
        else if (*argv[4]==100) Dekompresuj(argv[2], argv[3], tabkod);
    
        else printf("zle wywolanie");
    int i=0;
        for(;i<rozmiar;i++)
    
    
    
        printf("%c - %d - %x\n",tabkod[i].symbol,tabkod[i].dlkodu,tabkod[i].kod);
    
    
    return 0;
    
    }
    

    Kompiluje się, uruchamia...podaje mu plik, coś tam sobie liczy i kończy grzecznie działanie bez błedów.
  • REKLAMA
  • #6 9547690
    KRRySS
    Poziom 2  
    Posty: 3
    Ok, dzięki za pomoc, choć rozjeżdża się nadal..
  • #7 9548010
    lolcio
    Poziom 16  
    Posty: 133
    Pomógł: 29
    Ocena: 8
    A to już pewnie wina algorytmu :) Takie błedy są trudne w wykryciu...

Podsumowanie tematu

✨ Użytkownik zgłasza problem z implementacją algorytmu kodowania Huffmana w języku C, używając środowiska Dev-C++. Mimo braku błędów kompilacji, program nie działa poprawnie. Użytkownicy sugerują, aby sprawdzić, czy parametry są poprawnie przekazywane do programu, co może prowadzić do przekroczenia zakresu tablicy. Zwracają również uwagę na brak komentarzy w kodzie, co utrudnia jego analizę. Dodatkowo, wskazują na konieczność ustawienia kompilacji na standard C, a nie C++. Użytkownik potwierdza, że problem nadal występuje, co może sugerować błędy w algorytmie.
Wygenerowane przez model językowy.
REKLAMA