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 geparst

    IMPORTANT
    Achtung das dynamische Array wieder freigeben bei erflogreicher Suche oder und
    EOF des Dateidiskriptor
    sonst drohen Speicherleaks aufm HEAP im RAM deines Rechner

    Patternmatch 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 einliest

    if(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


Anmelden zum Antworten