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 - Bytez.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)T9TESTNach dem Unpackvorgang:
aaaaaaaaaaaaaaaaatttttttttttt3333333333333399999999TT9TESTTTTTTTTTTTTTTTTTTTJetz 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.. !