textdatei lesen,bearbeiten und wieder in neue textdatei schreiben
-
Hallo ihr Lieben,
ich hab ein Problem und keine Ahnung wie ich es lösen soll.
Ich habe eine Textdatei die wie folgt aussieht:
0,38,2,192.168.0.10,H2003480000000000000024B0,38,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,38,1,192.168.0.10,H2003480000000000000024BB,38,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,38,3,192.168.0.10,H200348000000000000002457,38,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,39,2,192.168.0.10,H2003480000000000000024B0,39,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,39,1,192.168.0.10,H2003480000000000000024BB,39,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,39,3,192.168.0.10,H200348000000000000002457,39,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,40,1,192.168.0.10,H2003480000000000000024BB,40,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,40,2,192.168.0.10,H2003480000000000000024B0,40,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,40,3,192.168.0.10,H200348000000000000002457,40,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,
0,SUMMARY,1,192.168.0.10,H2003480000000000000024BB,40,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=20DB
0,SUMMARY,2,192.168.0.10,H2003480000000000000024B0,40,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=20DBDies ist nur ein Auszug aus der Datei. Die Datei kann über 100.000 Datensätze beinhalten. Ich habe versucht mein Anliegen mit Excel zu lösen..allerdings kommt Excel mit diesen Datenmengen nicht klar.
Die Textdatei soll nun nach einem Tag z.B. H2003480000000000000024BB durchsucht werden und zählen wie oft der Tag mit den Einstellungen z.B Vortest W0 AT_P7 und ATTRIB FS=27DB vorkommt.
Die Anzahl soll in einer neuen Textdatei gespeichert werden.
Ich habe als Programmierumgebung den BorlandBuilder 6 zur verfügung.
Die SUMMARY-Einträge dürfen nicht gezählt werden!
Mir würde es auch schon helfen wenn in einer der neuen Textdatei nur noch der Tag und die Einstellungen z.B. Vortest W0 AT_P7,ATTRIB FS=27DB stehen und der Rest rausgelöscht wäre. Inklusive der SUMMARY.Ich hoffe man versteht mein Problem.
Liebe Grüße
Tobias
-
Hallo
Verwende TStringList, TFileStream oder std::fstream um die Datei einzulesen, und die entsprechenden String- oder std::string-Methoden um die einzelnen Zeilen zu parsen.
bis bald
akari
-
Hallo akari,
hast du mal ein Beispiel ?
Ich bin leider nicht so gut im Programmieren.Ich habe bis jetzt das er die Datei mit ifstream öffnet und mit getline in ein Memo schreibt.
Jetzt müsste ich wissen wie ich das Memo durchsuche, bearbeite und wieder schreibe.Oder kann ich die Prüfung auch wärend des einlesen machen? Also das er quasi direkt jede Zeile auf den Tag und die Einstellungen überprüft die ich vorher in einer CheckBox oder so ausgewählt habe und auch nur diese in das Memo schreibt?
Liebe Grüße
Tobias
-
Memo1->Lines->LoadFromFile( "datei.txt" ); for( int i = 0; i < Memo1->Lines->Count; i++ ) { if( Memo1->Lines->Strings[i] == "irgendwas" ) // mach was } Memo1->Lines->SaveToFile( "datei.txt" );
das ganze ifstream Gedöns brauchts nicht.
grüssle
-
Memo1->Lines->LoadFromFile( "test.txt" ); for( int i = 0; i < Memo1->Lines->Count; i++ ) { if( Memo1->Lines->Strings[i] == "H200348000000000000002483" ) { ShowMessage("Gefunden"); } } Memo1->Lines->SaveToFile( "datei1.txt" );
Ich habe damit mal ein Test gemacht. Allerdings wird die Message nie angezeigt. Kann es sein das es nicht geht weil in der Zeile alles hintereinander weggeschreiben wird und er daher nix findet?
Lieben Gruß
TobiEdit: Der gesuchte Tag steht auf jedenfall in der txt-Datei
-
is klar, dass da nichts kommt. Du vergleichst den kompletten String mit einem Fragment.
Mach mal:
if( Memo1->Lines->Strings[i].Pos("H200348000000000000002483") > 0 ) // dann gibts auch die Meldung
grüssle
-
Und ich würde dringend empfehlen TStringList statt TMemo zu verwenden. Das ist um ein vielfaches schneller... Zumindest beim Einlesen und / oder Hinzufügen von Zeilen.
-
Super das geht !!
for( int i = 0; i < Memo1->Lines->Count; i++ ) { if( Memo1->Lines->Strings[i].Pos("H200348000000000000002483") > 0 ) { Label1->Caption=i; } }
Ich öffne die Textdatei jetzt mit öffnen des Porgrammes. Jetzt würde ich gerne in der Zeile wo er den Tag gefunden hat noch nach den Einstellungen suchen und die Summe wie oft diese Bedingung vorgekommen ist ausgeben.
Kann ich einfach eine 2. Schleife nehmen und ab dem Wert der Variable i weiter zählen?Lieben Gruß
Tobias€dit: Wieso findet er den Tag so 327 mal und wenn ich z.B. <2 schreibe findet er ihn 1087 mal?
-
wenn du dem Label wirklich i zuweist wird nicht die Anzahl sondern immer die Position des letzten gefundenen Elements angezeigt...
int anzahl = 0; for( int i = 0; i < Memo1->Lines->Count; i++ ) { if( Memo1->Lines->Strings[ i].Pos("H200348000000000000002483") > 0 ) { anzahl++; Label1->Caption=anzahl; } }
schau dir mal die Methode Pos von AnsiString in der Hilfe an, dann weißt du was sie zurückgibt
bei ">0" ist die Bedingung immer dann wahr wenn der Suchtext irgendwo in der Zeile ist
bei "<2" ist die Bedingung nur dann wahr wenn der Suchtext an Position 1 der Zeile steht, d.h. wenn die Zeile mit dem Suchttext beginnt oder wenn der Text gar nicht enthalten ist, weil dann liefert Pos nämlich 0 zurück und das ist bekanntlich auch kleiner 2
-
Danke!
War allerdings nur ein TestUnd die Hilfe läuft unter Win7 leider nicht mehr... Wie lesen ich den jetzt in der Zeile "weiter"?
0,38,2,192.168.0.10,H2003480000000000000024B0,38,1,ATTRIB ANTS=1,ATTRIB SESSION=1,ATTRIB IDTIMEOUT=100,ATTRIB SCHEDOPT=0,ATTRIB TAGTYPE=EPCC1G2,ATTRIB NOTAGRPT=1,ATTRIB WRTRIES=3,ATTRIB DENSEREADERMODE=0,Vortest W0 AT_P7,ATTRIB FS=27DB,Ich stehe ja quasi an der stelle H2003480000000000000024B0 und ich will in dieser Zeile noch das Ende lesen und überprüfen. Also ob beispielsweise Vortest W0 AT_P7 und ATTRIB FS=27DB gegeben ist.
Meine Überlegung war sofor( int x = i; x < Memo1->Lines->Count; x++ ) { if( Memo1->Lines->Strings[x].Pos("ATTRIB FS=27DB") > 0 ) { //mache irgendwas } }
geht nur leider nicht.
-
du mußt ja nur prüfen ob in der gleichen Zeile auch der andere Text mit drin steht, dazu brauchst du aber keine 2. Schleife, sondern nur einen 2. Vergleich für die Zeile i
-
Das habe ich auch schon getestet
if( Memo1->Lines->Strings[ i].Pos("H200348000000000000002483") > 0 &&Memo1->Lines->Strings[ i].Pos("ATRRIB FS=30DB"))
geht nur leider nicht
-
beim 2. Vergleich fehlt etwas:
if( Memo1->Lines->Strings[ i].Pos("H200348000000000000002483") > 0 && Memo1->Lines->Strings[ i].Pos("ATRRIB FS=30DB") > 0 )
-
sorry das hab ich vergessen zu kopieren! war aber drin ! und ging nicht!
-
gibt es das in dieser Kombination im Text überhaupt? in einer Zeile?
-
ich habs
for( int i = 0; i < Memo1->Lines->Count; i++ ) { if( Memo1->Lines->Strings[i].Pos("H200348000000000000002483") > 0 && Memo1->Lines->Strings[i+1].Pos("Vortest W30 AT_P5") > 0 && Memo1->Lines->Strings[i+1].Pos("ATTRIB FS=30DB")) { a++; } } Label1->Caption=a;
Er hat in dem Memo eine Zeile der Textdatei auf zwei Zeilen verteilt.. deswegen i+1.
Jetzt dürfen nur die Sammary´s nicht gezählt werden. Kann man in die IF-Abfrage ein != "ungleich" eibauen !? Wenn ja an welche Stelle ?
Liebe Grüße
Tobias
-
So wie ich das sehe suchst du nach einer Möglichkeit die einzelnen Strings zu zerlegen und mit den einzelnen Value`s dann was anzustellen. Mal aus der Hüfte geschossen würd ich das so machen...
Schmeiss dir ein TMemo und nen TButton auf ne Form und probiers mal so.
TStringList *pListe = new TStringList(); // deine zu ladende Datei pListe->LoadFromFile("test.txt"); // erste Zeile der kompletten Datei anzeigen Memo1->Lines->Add(pListe->Strings[0]); // Detail Liste bauen TStringList *pListeDetail = new TStringList(); // es gibt da die "ominöse" Sache names 'CommaText' die genau // das macht was du brauchst // das Trennzeichen feytlegen pListeDetail->Delimiter = ','; // auf true setzen, sonst wird auch bei Leerzeichen und Umbrüchen geteilt pListeDetail->StrictDelimiter = true; // splitten pListeDetail->CommaText = pListe->Strings[0]; // Jetzt kannst du die einzelnen Listen Memo1->Lines->Add("=======alle TeilStrings einzeln der Zeile [0] ======="); // und noch fix alle TeilStrings der ersten Zeile aus deiner Datei anzeigen for(int i = 0; i < pListeDetail->Count; i++ ){ Memo1->Lines->Add("TeilString [" + IntToStr(i) + "] : "+ pListeDetail->Strings[i]); // ... was mit den superduperoberkrasstollen Teilstrings machen ... } // Listen hinterher löschen nicht vergessen ;) delete pListeDetail; delete pListe;
so kommst du ganz einfach an jeden Teilstring der in der Datei steht und kannst die nach belieben verwursten.
MfG
TFX
-
StrictDelimiter gibt es definitiv beim Builder 6 noch nicht.
-
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String dateiname="datei.txt";
String tag="H2003480000000000000024BB";
String vortest="Vortest W0 AT_P7";
String attrib="ATTRIB FS=27DB";
int count=0;
TStringList *datei=new TStringList();
datei->LoadFromFile(dateiname);
for(int i=0;i<datei->Count;i++)
{
if(datei->Strings[i].Pos(tag)&&datei->Strings[i].Pos(vortest)&&datei->Strings[i].Pos(attrib)) count++;
}
delete datei;
Label1->Caption = IntToStr(count);
}
-
void __fastcall TForm1::Button1Click(TObject *Sender) { String dateiname="datei.txt"; String tag="H2003480000000000000024BB"; String vortest="Vortest W0 AT_P7"; String attrib="ATTRIB FS=27DB"; int count=0; TStringList *datei=new TStringList(); datei->LoadFromFile(dateiname); for(int i=0;i<datei->Count;i++) { if(datei->Strings[i].Pos(tag)&&datei->Strings[i].Pos(vortest)&&datei->Strings[i].Pos(attrib)) count++; } delete datei; Label11->Caption = IntToStr(count); }
-
chamod schrieb:
StrictDelimiter gibt es definitiv beim Builder 6 noch nicht.
dann entferne die Leerzeichen und Zeilenumbrüche halt von Hand und lass den StrikDelimiter weg. Ist doch das selbe in grün...
MfG
TFX