Datei "durchscannen" und säubern
-
hy ,
das problem liegt auf der hand .. jedes darzustellende \ muss durch \\ angebenen werden. ist klar dass er die datei nicht findet ..
ebenfalls ein " muss durch \" und ein ' durch \' dargestellt werden ..
-
Ja, es war mir nach 5 Minuten auch offensichtlich und ich habs geändert. Trotzdem danke.
Nun doch noch eine kurze Frage: Du speicherst ja in deinem Codeteil das ganze File in einem Array, das funzt ja auch wunderbar aber ich konnte dem Datenblatt gerade entnehmen, dass nicht alle 63-er gelöscht werden sollen sondern nur ganze sog. ScannerMeldungen. Das sind die mit dem Header den ich ein paar Posts vorher geschrieben habe. Sie haben z.B. im Header zuerst die Länge, danach der timestamp, dann der typ und schlussendlich die eigentlichen daten. Der Typ ist hierbei wichtig. Wenn der 63 ist sollte es übersprungen werden. Ich verlange kein komplett funktionstüchtigen Codeteil, ich würd nur gerne wissen wie ich das auslesen kann und wie danach weiterverarbeiten und ne Abfrage draus machen. Dass es mit .read gehen sollte weiss ich. Sorry wenn ich so viel Fragen stelle aber mir ist das ganze binärverarbetungszeugs irgendwie noch neu.
-
Hy ,
naja du suchst , wenn ich es richtig verstehe nach einem Teil einer kl. struktur, die aus(Länge , Timestamp, typ , daten) bestehen ..nämlich nach typ=0x63.
jetzt muss du dir überlegen wieviel bytes jeweils deine elemente der struktur haben (zb länge = 4 bytes ), zb.timestamps = 4 bytes , zb.typ = 1 byte , zb. daten = variable 20 bytes) //nur bsp.grössen
dann musst du dynamisch abfragen , sich (hier in diesem bsp ) an bytestelle
9 die 0x63 befindet. wenn ja kannst du die anzahl der bytes (hier 4+4+1+20 = 29) getrost wegschmeissen ..Achtung: Du musst dir überlegen wo (für bsp länge , also 4 bytes) das erste byte liegt und wo das letzte ..
-
Danke für die Erklärung. Mir ist der Ablauf was ich machen müsste eigentlich fast immer ziemlich klar da ich vorher schon nicht wenig Programmiererfahrungen hatte. Mein grösstes und fast einziges Problem ist die Sprache C++ an sich, also der Code. Ich kann mir genau vorstellen was eine Applikation machen muss um dazu zu kommen nur finde ich selten (auch anhand des MSDN) 100%ig raus wie es nun mit dem Code ausschaut. Es gibt irgendwie immer 10 Möglichkeiten z.B. ein File zu öffnen und anfangs verwirrt das denke ich viele. Deshalb frage ich hier so viel bis ich die Materie etwas vertieft habe, hoffe das stört nicht.
Zum Programm zurück: Wie gesagt verstehe ich WAS GENAU er machen müsste damit ich zum gewünschten Ergebnis komme, ich peile aber nicht wie ich das realisieren soll. Hier erstmal die gesamte Funktion (filename ist nur vorübergehend statisch aus Testzwecken):
CString filename = "C:\\datei.pt2"; CString prFilename = filename + ".pr"; int arrayLenght; WORD *array; //WORD = 16bit unsigned int CFile file(filename, CFile::modeRead); //Open file (binary reading is standard) DWORD fileLenght = file.GetLength(); //Lenght of the current file (DWORD = 32bit unsigned int) arrayLenght = (fileLenght / sizeof(WORD)); //WORD = 16bit unsigned int array = (WORD*) calloc(arrayLenght, sizeof(WORD)); file.Read(array, arrayLenght*sizeof(WORD)); //The whole file is in the BYTE Array 'array' WORD lenght; //WORD = 16bit unsigned int DWORD timestamp; //DWORD = 32bit unsigned int BYTE type; //BYTE = 8bit unsigned int BeginWaitCursor(); CFile prFile(prFilename, CFile::modeCreate | CFile::modeWrite); //Open the .pr File (ProcessFile) for(int i = 0; i < fileLenght; i++) { WORD varLenght = file.Read(&lenght, 2); //Read the lenght (2 Byte) DWORD varTimestamp = file.Read(×tamp, 4); //Read the timestamp (4 Byte) BYTE varType = file.Read(&type, 1); //Read the type (1 Byte) DWORD data; DWORD varData = file.Read(&data, lenght); if(type != 63) { prFile.Seek(0,CFile::end); prFile.Write(lenght, 2); prFile.Write(timestamp, 4); prFile.Write(type, 1); prFile.Write(data, lenght); } } prFile.Close(); //Close the ProcessFile EndWaitCursor(); file.Close(); //Close the main-file free(array); //Clear memory (IMPORTANT)EDIT: Ich hatte nur n paar logische Fehler, jetzt sollte im oberen Part eigentlich soweit alles nicht schlceht sein. Hab nur Probleme mit dem write. Er sagt immer
"cannot convert parameter 1 from 'unsigned short' to 'const void *'". Wie kann ich das lösen? Danke im Voraus.
-
Hy ,
also zu deinem Parameterübergabeproblem :
ich nehme an du benutzt CFileDialog ?!
dann füge einfach den cast ein :CString path = cfd.GetPathName(); //CString nach char* casten //LPCTSRT = long pointer const string char * szMyString = (char *) (LPCTSTR) path;dann sollte es wieder funzen ...
PS. : deine for-schleife kannste optimieren .. mach ne while draus und überprüfe dann erst bei byte(zb 9)weiter .. nicht jedes byte durchgehen und checken.
Wieso eigentlich free? kannst doch delete [] arrayname machen ..
-
Ich habs immernoch nicht geschafft. Nun ist das ganze Programm rundum fertig und ich hab eigentlich alle Klassen, Abfragen, rekursive Scans etc. gemacht. Es hapert nur an dieser einen Funktion. Der Quelltext ist eigentlich gleich geblieben also brauche ich den nicht nochmal zu posten, man kann ihn oben einsehen. Die normale .pt Datei ist meistens so von 3-5MB. Wenn ich es ausführe wird die .pt.pr Datei locker mal schnell 700MB gross. Er schreibt wahnsinnig viel Schrott rein und ich weiss nicht wie ich das ganze irgendwie "intelligenter" scannen und schreiben lassen kann. Was mache ich falsch? Beispiele? Wäre dankbar um jede Hilfe.
-
hy ,
1.) weil du nirgends deine werte aus dem eingelesen array benutzt?
(willst du es überhaupt benutzen ansonsten muss du in der schleife
sowieso dafür sorgen das dein filepoiter vorwärtsgerücktwird )
2.) du immer die selben bytes interpretierst und für jedes byte!!
(so tun würdest als ob es ein header bate ist und somit immer 4+2+1 bytes
in die datei schreibst)// dieser vorschlag gilt nur wenn du statt unsignde short byteweise einliest // habe ich nicht getestet nur so provisorisch aufgestllt.. int i=0; WORD varLenght=0; DWORD varTimestamp=0; BYTE varType=0; while( i < fileLenght ) { //Read the lenght (2 Byte) varLenght = array[i]<<8 ; varLenght = varLenght | array[i+1] ; //Read the timestamp (4 Byte) varTimestamp = array[i+2]<<24 ; varTimestamp = varTimestamp | array[i+3]<<16; varTimestamp = varTimestamp | array[i+4]<<8; varTimestamp = varTimestamp | array[i+5]; //Read the type (1 Byte) varType = array[i+6]; // falls die struktur dynmisch in der grösse ist .. hier anpassen // ist dein data 2 bytes ? oder ist es danamisch // also sowas wie sizeof(length) = entspricht 2 //oder in length ist der wert zb 20 , die anzahl der bytes if(type != 63) { prFile.Seek(0,CFile::end); prFile.Write(lenght, 2); prFile.Write(timestamp, 4); prFile.Write(type, 1); prFile.Write(data, lenght); } i+=7; //anzahl bytes der struktur // falls die struktur dynmisch in der grösse ist .. hier anpassen //also die 7 ggf um 2 erhöhen oder den dynamischen wert. // i+=(7+lenght) ; }
-
Wenn ich ehrlich bin versteh ich davon keinen Meter. Dass du Byte für Byte ausliest und in ein Array speicherst ist mir klar aber du liest ja nicht direkt das File aus weil du kein CFile.read() benutzt oder seh ich das falsch? Sobald ich irgend einen Scheiss in das prFile schreiben will mit dem Write gibt er mir einen Fehler aus. Zum "i += 7" fällt mir auch absolut nichts ein. Langsam hab ich das Gefühl ich gebs auf...
-
Herzlich willkommen in der welt von c++
, gib bloss schnell auf und du hast deutlich mehr freizeit ..*g*Also jetzt nochmal für die steinmetze zum mitmeisseln..
Ich bin davon ausgegangen ,dass du den oberen teil von dir/mir übernimmst und es mit byte inliest..deshalb habe ich kein read() usw geschrieben ..(mitdenken..)Ausdrucksbeschreibung:
varTimestamp = varTimestamp | array[i+3]<<16;
//shifte das i+3 byte um 2 byte nach links //4 3 2 1
//weil varTimestamp (4 byte type) ist, steht jetzt das i+3 byte 0x00**0000 an
//der ** position//i+=7; ist das gleiche wie i= i+7 nur kürzer .. sollte aber bekannt sein
das mit dem schreiben könntest du auch anders machen ..
in einem zusätzleichen array speichern ..und am ende alles schreiben..
So muss jetzt leider nach hause..
und kann erst morgen wieder reinschauen (mein arbeitgeber sei dank*g*)..habe so das gefühl du schriebst wieder*g*
cu Andreas
-
So, endlich habe ich es geschafft. Das Ganze funktioniert einwandfrei und die Dateien verlieren 2/3 ihrer ursprünglichen Grösse weil diese unnötigen ScannerMeldungen (die ich ja jetzt rausfiltere) ziemlich viel Platz brauchen. Vielen Dank für deine Hilfe wuTangl, warst ja der Einzige der mir geholfen hat
. Anfangs bin ich immer etwas schwerfällig was das angeht aber man sollte auch beachten dass ich erst seit 2 Wochen C++ mache. Ich hab heute morgen einfach mal meine letzte Logik hervorgeholt und versucht das Ganze so anzuschauen wie es der PC macht, hat eigentlich gut geklappt.Für die die es noch interessiert noch die fertige Scanfunktion:
BOOL CScanFilterDlg::ProcessFile(CString currentFile) { UpdateData(TRUE); int arrayLenght; int i = 0; BOOL ok; CString file; CString prFilename = currentFile + ".pr"; WORD varLenght = 0; DWORD varTimestamp = 0; BYTE varType = 0; BYTE *array; CFile cfile(currentFile, CFile::modeRead); //Open file (binary reading is standard) DWORD fileLenght = cfile.GetLength(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////SAVE THE WHOLE FILE IN AN ARRAY////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// arrayLenght = (fileLenght / sizeof(BYTE)); array = (BYTE*) calloc(arrayLenght, sizeof(BYTE)); cfile.Read(array, arrayLenght*sizeof(BYTE)); CFile prFile(prFilename, CFile::modeCreate | CFile::modeWrite); //Create ProcessFile ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////MOST IMPORTANT SCANNING LOOP///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// while(i < fileLenght) { //Read the Lenght (2 Byte) varLenght = array[i]; varLenght = varLenght | array[i + 1] << 8; //Read the Timestamp (4 Byte) varTimestamp = array[i + 2] << 24; varTimestamp = varTimestamp | array[i + 3] << 16; varTimestamp = varTimestamp | array[i + 4] << 8; varTimestamp = varTimestamp | array[i + 5]; //Read the Type (1 Byte) varType = array[i + 6]; if(varType != 0x63) { prFile.Seek(0,CFile::end); //Jump to End of File prFile.Write(&array[i], (7 + varLenght)); //Write whole Message } i = (i + 7 + varLenght); //Set Cursor on next MessageStart } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////COMPLETE PROCESS BY CLOSING, DELETING AND RENAMING THE NECESSARY FILES/////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cfile.Close(); //Close OldFile prFile.Close(); //Close ProcessFile cfile.Remove(currentFile); //Remove OldFile prFile.Rename(prFilename, currentFile); //Rename ProcessFile free(array); //Clear Memory (IMPORTANT) return ok; //Return ok UpdateData(FALSE); }