Datei parsen, aber wie
-
Hi Leute,
eine Datei einlesen ist ja weniger ein Problem. Aber ein Problem ist es (für mich) wenn ich eine Datei die im Stil einer HTML datei geschrieben ist richtig auslesen will. Die Datei sieht so aus<...> <txt:TXT ... ... <item> <title>Titel der Seite</title> <link>http://www.link.zur/Seite/</link> </item> <item> <title>Titel der anderen Seite</title> <link>http://www.link.zur/anderen/Setie/</link> </item> </txt:TXT>
Wie kann ich das jetzt in z.B. ein Struktur-Array einlesen? So das nur der Titel und der Link in mein Struktur-Array geschrieben wird? Also alles zwischen <titel></titel> und <link></link>
struct links{ char titel[255]; char link[255]; };
MfG und Danke
Basti
-
du schreibst dir erstmal ne Funktion die das Suchmuster bekommt
Grober Ansatz (Dieser Algorithmus entspricht im Grunde einer BRUTEFORCE - Suche)
in diser methode erstellst du dynamisch einen Zeiger auf ein Charakter
-feld was exakt genauso gross ist wie der zu suchende String bsp.: <LINK>Du öffnest jetzt die Datei (htm-file) und liesstin einer Schleif in das dynamische Array ein und zwar solange bis die Zeichenanzahl des Suchmuster erreicht ist.
Dann kannst du mit
strcmp(... , ...);
das was im dynamischen Feld steht mit deinen Suchmuster vergleichen
ist es nisch gefunden liesst du aus der datei beginnend ab dem zweitenZeichen
und und soweiter und sofort. Du verschiebst also bei fehlgeschlagener Suche immerden Dateidiskriptor um ein Byte und liest den möglichen Stream neu ein
der dem Suchmuster entsprechen kann!Wenn Du es findest "strcmp" gibt 0 zurueck steht der Dateidiskriptor hinter
dem gefunden String (bsp.: hinter <LINK> Tag) jetzt kannst du nun zeichenweise auslesen bis zum beginnenden zeichen "<" des Abschlusstag "</LINK>" und
schon hast du geparstIMPORTANT
Achtung das dynamische Array wieder freigeben bei erflogreicher Suche oder und
EOF des Dateidiskriptor
sonst drohen Speicherleaks aufm HEAP im RAM deines RechnerPatternmatch ist nisch so leicht schnell und kurz zu machen (erklären)
mfg sclearscreen
-
ich würd's ein klein wenig anders machen, denk ich.
Der text wird zuallererst mal zeichenweise durchgearbeitet. wenn irgendwo ein '<' steht, wird der Text, der bis zum nächsten '>' steht in eine Variable v_order geschrieben. Anschließend wird überprüft, ob das erste Zeichen ein '/' ist (oder was auch immer deine Tags wieder schließt)
Ich würde jetzt für sämtliche möglichen Befehle einen String-Array machen
(char *Orders[30]={"hallo","welt", ..};)
nun musst du nicht zigtausend strcmps machen, sondern brauchst nur eins in einer Schleife. vielleicht ist auch iene Tabelle sinnvol, in der du jedem Befelh eine Nummer zuweist. Diese brauchst Du dann nur noch auf eine dynamische Liste (einen stack) zu legen und schon kannst Du überprüfen, welcher tag aktuell ist. (will jetzt nicht die Funktion von Stapelspeichern erklären. da solltest Du mal im ASM-Forum nachfragen und vorher evtl. die FAQs durchkramen)cYa
DjR
-
oder man passt die quelldatei etwas an, dass sie den xml standard einhält (brauchts nicht viel, das sieht ziemlich danach aus) und nimmt sowas wie tinyxml, oder baut sich sowas selber (is net der brüller schwer, wie oben beschrieben)
-
Ich hab hier nen code, den ich mal für'n Prog im VB gebastelt habe. so in der Art kannste das umsetzen (will's jetzt nicht nach C umsetzen, also verzeiht bitte, dass es BASIC ist)
hier wird eine Datei nach einem Objekt durchsucht, das in "<+..+>" oder "<-..->" steht. dabei öffnet das 'tag' mit dem + eine Ebene und das 'tag' mit dem - schließt sie wieder. Hab mir damit ein Notizbuch mit Kapiteln geschrieben.
Dim i As Integer Dim l As Integer Dim Anfang As Integer Dim ActiveNode As String ReDim Data(1) i = 0 l = 0 Form1.Tree1.Nodes.Add , tvwFirst, "Notizen", "Notizen" ActiveNode = "Notizen" DataNo = 0 Data(DataNo).NodeKey = ActiveNode While i < Len(Contents) i = i + 1 Select Case Mid(Contents, i, 1) Case "<" l = 1 Case "+" If l = 1 Then l = 2 Anfang = i + 1 ElseIf l = 2 Then i = i + 1 l = 0 If Mid(Contents, i, 1) = ">" Then Form1.Tree1.Nodes.Add _ ActiveNode, tvwChild, _ Mid(Contents, Anfang, (i - Anfang) - 1), _ Mid(Contents, Anfang, (i - Anfang) - 1) ActiveNode = Mid(Contents, Anfang, (i - Anfang) - 1) DataNo = DataNo + 1 ReDim Preserve Data(DataNo) Data(DataNo).NodeKey = ActiveNode i = i + 2 End If Else Data(DataNo).text = Data(DataNo).text + Mid(Contents, i, 1) End If Case "-" If l = 1 Then l = 3 Anfang = i + 1 ElseIf l = 3 Then i = i + 1 If Mid(Contents, i, 1) = ">" Then ActiveNode = Form1.Tree1.Nodes.Item(Mid(Contents, Anfang, (i - Anfang) - 1)).Parent.Key l = 0 End If Else Data(DataNo).text = Data(DataNo).text + Mid(Contents, i, 1) End If Case Else If l = 0 Or l = 1 Then Data(DataNo).text = Data(DataNo).text + Mid(Contents, i, 1) End If End Select Wend
cya
DjR
-
Danke für die Antworten, werde mir die verschiedenen Möglichkeiten mal durch den Kopf gehen lassen.
MfG
Basti
-
Also, da die Datei immer gleich aufgebaut ist und der Benutzer die Datei auch nicht verändern kann hab ich es mir jetzt ganz einfach gemacht.
Dies ist die "Routine" die den link einliestif(line[1] == '<' && line[7] == '>'){ // Wenn <title> for(int i=8;i<=255;i++){ // Ab '>' beginnen if(line[i] != '<' && line[i]+1 != '/' && line[i+6] != '>'){ // Wenn </title> sprintf(ch,"%c",line[i]); // Einzelnes Zeichen speichern strcat(data[j].title,ch); // Einzelnes Zeichan an link[i] anhängen } else { break; } } }
Es geht vielleicht noch anders. Ich hätte es mit 'strstr' lösen können aber so läufts auch.
MfG und danke
Basti
-
zumal strstr auch nichts anderes tut, als den string zeichenweise durchzugehen