Kleines Problem



  • Hallo,

    Müssen ein Projekt Packprogramm coden und hängen grad ein bisschen fest:

    #include <iostream.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    long filesize(FILE *stream);
    int crunch(FILE*,char[50]);//Packalgorithmus
    #pragma argsused
    int main(int argc, char* argv[])
    {
     char filename[50];
     cout << "Dateiname eingeben: "; cin >> filename;  //nur zum testen
     FILE *input;
     if ((input = fopen(filename,"rb"))==NULL){cout << "Error opening " << filename; return 1;}
     crunch(input,filename);
            return 0;
    }
    //---------------------------------------------------------------------------
    int crunch(FILE* in, char fname[50])
    {
     char byte;            //Momentan eingelesenes Byte
     char oldbyte;         //Zuletzt eingelesenes Byte
     long outbytecounter=0; //Anzahl der momentan geschriebenen Bytes
     int countsamebytes=0;//Z„hlt Anzahl gleicher Bytes
     char crunchwrite[3];  //0=>Anzahl gleicher Bytes 1=>Byte
     FILE *output;         //Datei in die geschrieben wird
     if ((output = fopen("test.lcr","wb"))==NULL){cout << "Error writing to file. Disk is probably write-protected/full."; return 1;}
     char crunchbuffer;      //Zwischenspeicher für gepackte Bits
     cout << "Crunching " << fname << " (" << filesize(in) << " bytes)...\n";
     //ab da h„ngt er sich auf
    // fseek(in,0,0);          //Springt an erste Stelle der Datei
     fread(&oldbyte,1,1,in);  //Liest erstes Byte der Datei ein
     for (int inbytecounter=1;inbytecounter<filesize(in);inbytecounter++)
      {
       fseek(in,inbytecounter,0);              //Springt an Stelle des Dateizeigers
       fread (&byte, 1, 1, in);        //Liest ein Byte ein
       if (byte==oldbyte){countsamebytes+=1;}  //Wenn aktuelles Byte gleich dem zuletzt gelesenen Byte
                                               //wird der Counter um 1 erh”ht
       if (!(byte==oldbyte))              //Unterscheiden sich aktuelles und letztes Byte
        {
         crunchwrite[0]=251;              //werden Merker
         crunchwrite[1]=countsamebytes;   //und Anzahl der gleichen Bytes
         crunchwrite[2]=byte;             //und der Name dessen
         fseek(output,outbytecounter,0);
         fwrite(&crunchwrite[0],1,1,output);  //in die Ausgangsdatei geschrieben
         fseek(output,(outbytecounter+1),0);
         fwrite(&crunchwrite[1],1,1,output);
         fseek(output,(outbytecounter+2),0);
         fwrite(&crunchwrite[2],1,1,output);
         outbytecounter+=1;               //und der counter fuer die geschriebenen Bytez um 1 erhoeht
         countsamebytes=1;
        }
       oldbyte=byte;
     //  cout << "\r" << inbytecounter << " Bytez processed.";      //waaaah das geht hammer auf die geschwindigkeit
      }//Schleife l„uft bis Datei fertig eingelesen ist
     cout << "\nDone!";
    }
    //---------------------------------------------------------------------------
    long filesize(FILE *stream)
    {
     long curpos, length;
     curpos = ftell(stream);
     fseek(stream, 0L, SEEK_END);
     length = ftell(stream);
     fseek(stream, curpos, SEEK_SET);
     return length;
    }
    

    Das Programm sollte also die gleichen Bytes zählen und dann z.b. Merker/Anzahl gleicher, aufeinanderfolgender Zeichen/Zeichen ausgeben, bis der Code eben durch ist.

    Könnt ja mal testen.
    Vielen Dank im Voraus.

    <hume>Bitte Code-Tags verwenden!</hume>



  • Hallo,
    wo ist die Frage?



  • if (!(byte==oldbyte))              //Unterscheiden sich aktuelles und letztes Byte
        {
         crunchwrite[0]=251;              //werden Merker
         crunchwrite[1]=countsamebytes;   //und Anzahl der gleichen Bytes
         crunchwrite[2]=byte;             //und der Name dessen
         fseek(output,outbytecounter,0);
         fwrite(&crunchwrite[0],1,1,output);  //in die Ausgangsdatei geschrieben
         fseek(output,(outbytecounter+1),0);
         fwrite(&crunchwrite[1],1,1,output);
         fseek(output,(outbytecounter+2),0);
         fwrite(&crunchwrite[2],1,1,output);
         outbytecounter+=1;               //und der counter fuer die geschriebenen Bytez um 1 erhoeht
         countsamebytes=1;
        }
    

    hier hängen wir irgendwie fest, gibt nur falsches zeug aus! wasn' da falsch?



  • hier hängen wir irgendwie fest, gibt nur falsches zeug aus! wasn' da falsch?

    Ich bezweifle, dass dir das jemand mit diesen Informationen beantworten kann. Was heisst denn falsches Zeugs? Damit kann doch kein Mensch was anfangen. Ich finde den Code zudem nicht wirklich strukturiert.



  • Also erstmal coden wir erst so seit nem halben Jahr in C++.. etz mach uns halt netmal so runter!

    Er gibt in die Datei ausser dem Merker nix weiter rein!

    Und wir wollen dass er pro (gleiches) Byte in der Source-Datei folgendes ausgibt:
    Merker (Asc 251) - Anzahl gleicher Bytes - Byte

    z.B. Source: xxxxx
    Out: ¹5x



  • Von dem Code krig ich Kopfschmerzen. Viel zu viele Kommentare, viel zu wenig Leerzeilen. Und dann immer am Anfang jeder Funktion erstmal so'n Block von Variablendefinitionen. *argh*.



  • wenns dich stört dass der code kommentiert is beschwer dich bei unserm lehrer, ich hätt da sonst auch kan bock drauf
    ich weiß die deklarationen sin weng krass... des wird noch angepasst, es geht uns erst mal um den teil der NICHT geht



  • 1. was soll das ständige fseek, das genau da hinspringt wo du sowieso schon bist?
    2. FILE ist in <cstdio> definiert, die du aber gar nicht einbindest. Aber es gibt schon lange eine zu bevorzugende Alternative: ifstream und ofstream aus <fastream>
    3. verwendet man <iostream> und nicht <iostream.h>
    4. kann man auch mit ++ inkrementieren und muss nicht ständig +=1 schreiben
    5. Meinte 'der_held' mit "Und dann immer am Anfang jeder Funktion erstmal so'n Block von Variablendefinitionen." sowas:

    Statt:

    long filesize(FILE *stream)
    {
     long curpos, length;
     curpos = ftell(stream);
     fseek(stream, 0L, SEEK_END);
     length = ftell(stream);
     fseek(stream, curpos, SEEK_SET);
     return length;
    }
    

    lieber:

    long filesize(FILE *stream)
    {
      long curpos = ftell(stream);
      fseek(stream, 0L, SEEK_END);
      long length = ftell(stream);
      fseek(stream, curpos, SEEK_SET);
      return length;
    }
    

    6. was soll so ein Konstrukt:

    if (byte==oldbyte) ...
    if (!(byte==oldbyte))
    

    a) es gibt einen != Operator
    b) es gibt else



  • Erstmal danke, Helium.

    Zu 1. Dachten, das es daran liegen könnte, aber mittlerweile wissen wir das es
    unnütz ist.
    Zu 2. Unser Lehrer meint iostream.h passt!
    Zu 3. ^^
    Zu 4. Stimmt.
    Zu 5. Okay, ham wir umgeändert.
    Zu 6. Er springt aber in die Schleife rein, also passts doch oder..?

    Danke für Beitrag, aber irgendwie hilft uns das alles nich weiter...



  • fseek(output,outbytecounter,0); 
         fwrite(&crunchwrite[0],1,1,output);  //in die Ausgangsdatei geschrieben 
         fseek(output,(outbytecounter+1),0); 
         fwrite(&crunchwrite[1],1,1,output); 
         fseek(output,(outbytecounter+2),0); 
         fwrite(&crunchwrite[2],1,1,output); 
         outbytecounter+=1;               //und der counter fuer die geschriebenen Bytez um 1 erhoeht
    

    Wenn ich das richtig sehe passiert folgendes: Beim ersten Durchlauf ist outbytecounter=0. Lapidar gesprochen schreibst du den 'Merker' an Position 0 (outbytecounter), 'Anzahl gleicher Bytes' an Position 1 (outbytecounter+1) und 'Byte' an Position 2 (outbytecounter+2) und erhöhst den Counter um 1.

    D.H. im zweiten Durchlauf setzt du den 'Merker' an Position 1 (outbytecounter) und überschreibst damit die 'Anzahl gleicher Bytes' vom vorherigen Durchgang.

    Wenn ihr das Gefriemel mit fseek weg läßt, sollte es eigentlich einigermaßen funktionieren.



  • Jo, danke, jetzt hat sich einiges getan!

    So, nur wir macht man das jetzt das er die gleichen hintereinander kommenden Zeichen zusammenfasst?



  • Zu 2. Unser Lehrer meint iostream.h passt!
    Dann hat euer Lehrer nicht gerade viel Ahnung.

    Zu 3. ^^
    Dito 😉

    <iostream.h> ist prästandard, also seit etwa 6 Jahren nicht mehr aktuell. Und wie bereits gesagt ist FILE nicht in <iostream.h> definiert, sondern in <cstdio> bzw. <stdio.h>.
    Es mag sein, das eure konkrete Implementation so aussieht, das <iostream.h> <stdio.h> einbindet, aber das ist nicht portabel.

    Und warum setzt ihr überhaupt auf FILE, wenn C++ Streams doch viel bequemer sind? (Lass mich raten: euer Lehrer kennt die gar nicht.)

    Zu 6. Er springt aber in die Schleife rein, also passts doch oder..?
    In welche Schleife?
    Wie auch immer: Ich habe keinen Fehler gezeigt, sondern eine IMHO bessere Alternative.



  • lol kann sein dass der keine ahnung hat... is übrigens für die dos-konsole des programm, von wegen portabel und so muss da nix sein.
    des prog is noch in der arbeit, mir kommt es so vor als würde er von den 3 chars nur 2 schreiben oder eben die zeichen nicht zusammenfassen (glaube ich weniger), wenn das nun funktioniert müssen wir noch etwas einbauen falls das eingelesene byte das gleiche ist wie der merker, dass das prog nicht durcheinanderkommt



  • So, nur wir macht man das jetzt das er die gleichen hintereinander kommenden Zeichen zusammenfasst?

    Versteh ich zwar noch nicht ganz.



  • Also z.b. in der datei stehn etz 5 x hintereinander xxxxx
    und dann müssn wir's so coden das ¹5x dortsteht!



  • 1. crunchwrite[2]=byte; // <== muss oldbyte sein

    2. fopen("test.lcr","wb") // ihr erzeugt ein Binärfile. Ändert mal 'wb' in 'wt', dann sollte das erzeugte File eher euren Vorstellungen entsprechen.
    [edit]Mein Fehler: Das Schreiben in das File sollte dann allerdings eher so aussehen:
    fprintf(output,"%c%d%c",251,countsamebytes,oldbyte); [/edit]

    3. Die letzte Bytefolge wird übrigens verschluckt. Nach der for-Schleife müsst ihr die letzte Bytefolge noch speichern.



  • Oha,
    vielen Dank dir!

    Sind jetzt schon wesentlich weiter gekommen!



  • Hi,

    Sind jetzt kurz vorm Ende, haben nun noch ein kleines Problem:

    #include <iostream.h>
    #include <conio.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    long filesize(FILE *stream);    //liest Dateigröße aus
    int crunch(FILE*,char[50]);     //Packalgorithmus
    int decrunch(FILE*,char[50]);   //Un-Pack ownage
    #pragma argsused
    int main(int argc, char* argv[])
    {
     /*
     if (argv[0]==99)
      if (argv[1]!="")
       {
        fílename=argv[1];
        if ((input = fopen(filename,"rb"))==NULL){cout << "Error opening " << filename; return 1;}
        crunch(input,filename);
       }
     if (argv[0]==100)
      {
       filename=argv[1];
      }
     */
     char filename[50];
     cout << "Dateiname eingeben: "; cin >> filename;  //nur zum testen
     FILE *input;
     if ((input = fopen(filename,"rb"))==NULL){cout << "Error opening " << filename; return 1;}
     decrunch(input,filename);
     getch();   //der is auch bloß temporär
            return 0;
    }
    //---------------------------------------------------------------------------
    int crunch(FILE* in, char fname[50])
    {
     char byte;             //Momentan eingelesenes Byte
     char oldbyte[4];       //Zuletzt eingelesenes Byte
     long outbytecounter=0; //Anzahl der momentan geschriebenen Bytes
     char countsamebytes=0; //Z„hlt Anzahl gleicher Bytes
     char crunchwrite[3];   //0->Merker, 1->Anzahl gleicher Bytes, 2->Byte
     FILE *output;          //Datei in die geschrieben wird
     if ((output = fopen("test.lcr","wb"))==NULL){cout << "Error writing to file. Disk is probably write-protected/full."; return 1;}
     fprintf(output,"lamecrunch");
    
     char crunchbuffer;     //Zwischenspeicher für gepackte Bits
     cout << "Crunching " << fname << " (" << filesize(in) << " bytes)...\n";
     fread(&oldbyte[3],1,1,in); //Liest die ersten vier Byte der Datei ein
     fread(&oldbyte[2],1,1,in);
     fread(&oldbyte[1],1,1,in);
     fread(&oldbyte[0],1,1,in);
     for (int inbytecounter=1;inbytecounter<(filesize(in)+1);inbytecounter++)
      {
       fseek(in,inbytecounter,0);                //Springt an Stelle des Dateizeigers
       fread (&byte, 1, 1, in);                  //Liest ein Byte ein
       if (byte==oldbyte[0]){countsamebytes+=1;} //Wenn aktuelles Byte gleich dem zuletzt gelesenen Byte
                                                 //wird der Counter um 1 erh”ht
       if (!(byte==oldbyte[0]))                  //Unterscheiden sich aktuelles und letztes Byte
        {
         if (byte!=251)
          {
           if ((oldbyte[1]==oldbyte[2])&&(oldbyte[2]==oldbyte[3]))
            {
             crunchwrite[0]=251;                                     //werden Merker
             crunchwrite[1]=countsamebytes;                          //und Anzahl der gleichen Bytes
             crunchwrite[2]=byte;                                    //und der Name dessen
             fprintf(output,"%c%c%c",251,countsamebytes,oldbyte[0]); //in die Ausgangsdatei geschrieben
             outbytecounter+=1;                                      //und der counter fuer die geschriebenen Bytez um 1 erhoeht
             countsamebytes=1;
            }
           if (oldbyte[0]!=oldbyte[1])
            {
             fprintf(output,"%c",oldbyte[1]);
            }
          }
         if (oldbyte[0]==251)
          {
           fprintf(output,"%c%c%c",251,countsamebytes,oldbyte[0]);
          }
        }
       oldbyte[3]=oldbyte[2];
       oldbyte[2]=oldbyte[1];
       oldbyte[1]=oldbyte[0];
       oldbyte[0]=byte;
      }
     cout << "\nDone!" << outbytecounter << " Bytez written. Keek stinkt!";
    }
    //---------------------------------------------------------------------------
    int decrunch(FILE* in,char filename[50])
    {
     char origheader[13]="lamecrunch";
     char header[13];
     char size[100];
     char merker, anzahl, byte;
     int comparison;
     FILE* output;
     if ((output = fopen("out.lcr","wb"))==NULL){cout << "Error writing! ass"; return 1;}
     fread(&header,10,1,in);
     comparison=strcmp(header,origheader);
     if (comparison==0) //checkt ob die ersten 13 Bytez der Datei dem Header entsprechen
      {
       cout << "Header found. Decrunching...\n";
     //  fseek(in,0,10);
        for (int i=0;i<((filesize(in)+1));i++)
         {
          fread(&merker,1,1,in);
          cout << merker;
          if (merker=='û')                 //ab 3 Zeichen
           {
            fread(&anzahl,1,1,in);
            fread(&byte,1,1,in);
            for (int x=0;x<(anzahl+1);x++) //wird das Byte so oft geschrieben wie es vorhanden sein soll
             {
              fprintf(output,"%c",byte);
              cout << anzahl << byte<<"\n";
             }
           }
          if (merker!='û')                 //unter 3 Zeichen wird nur das Byte geschrieben
           {
            fprintf(output,"%c",merker);
           }
         }
       cout << "Done.";
      }
     if (comparison!=0)
      {
       cout << "Header not found. Not a valid lamecrunch file. Exiting...";
      }
    }
    //---------------------------------------------------------------------------
    long filesize(FILE *stream)
    {
     long curpos = ftell(stream);
     fseek(stream, 0L, SEEK_END);
     long length = ftell(stream);
     fseek(stream, curpos, SEEK_SET);
     return length;
    }
    

    Unsere Testdatei sah so ähnlich aus: aaaaaaaaaaaaaaaaatttttttttttt3333333333333399999999TEST

    Nach dem Packvorgang
    lamecrunch¹&a¹§t¹_3¹ô9¹(noch so'n zeichen)T9TEST

    Nach dem Unpackvorgang:
    aaaaaaaaaaaaaaaaatttttttttttt3333333333333399999999TT9TESTTTTTTTTTTTTTTTTTTT

    Jetz wissen wir nicht woran das liegt... das er vor dem TEST noch TT9 und danach die ganzen T's ausgibt...

    Danke im Voraus,
    Brauchen ne Hilfe so schnell wie möglich, morgen ist Abgabetermin...



  • Leute bitte... Helium, Killing me softly.. irgendwer.. !

    😞


Anmelden zum Antworten