String auslesen

DaRi
2011-03-07
2011-03-19
  • DaRi - 2011-03-07

    Hallo,

    ich möchte aus einer Datei einen String bis zum Zeilenumbruch auslesen.
    Der String ist grob gesagt in 3 Bereiche unterteil: 1.Name, 2.Datentyp, 3. Wert -> "Teil1 UI16 8".
    Es sind mehrere Zeilen (und somit auch Strings) untereinander.
    Letztendlich möchte ich immer in jeder Zeile den Wert des entsprechenden Teils ermitteln.

    Die Datei habe ich mit Sysfileopen geöffnet und wäre jetzt für das Auslesen bereit.

    Ich hoffe dass mir jemand damit etwas helfen kann, da ich ein absolutes "Greenhorn" bin.

    Vielen Dank!!!

     
  • SpeedFreak - 2011-03-07

    hallo

    ich benutze zwar twincat (das beckhoff-derivat von codesys), aber das dürfte egal sein. hier gibt es speziell für das lesen (und auch schreiben) von strings (zeilenweise) FBs namens FB_FileGets bzw. FB_FilePuts. damit kann man dateien zeilenweise lesen/schreiben.

    da du geschrieben hast, dass du greenhorn bist, will ich dir vielleicht noch paar worte dazu mitgeben.
    die beiden fb weisen eine "tücke" auf (also ich bin zumindest drüber gestolpert...) genau wie die fb zum datei oeffnen/schließen benötigen diese mitunter mehre sps-zyklen um einmal komplett abgearbeitet zu werden. das läuft so, dass man den fb aufruft und unter anderem eine variable namens "execute" mit true übergibt. der fb meldet darauf hin "busy" zurück.
    wenn du jetz im nächsten zyklus wieder an der stelle vorbei kommst und wieder mit "execute := true" aufrufst, während der fb, aber noch "busy" meldet... geht das ganze nach hinten los. also vor "execute := true" erst prüfen , ob "busy = false". ich mach das meist so:

    CASE Step OF

    0:
    ;
    1:
    FB_SchreibenS( bExecute := FALSE);
    FB_SchreibenS( sNetId := '',
    hFile := uiFileHandle,
    sLine := sLine,
    bExecute := TRUE,
    tTimeOut := t#3s,
    bError => bSchreibenError,
    nErrId => diSchreibenErrorID);
    Step := Step + 1;

    2: (Prüfen ob Schreiben erfolgreich oder Fehler)
    (Im Fehlerfall Fehlercode auslesen)

    FB_SchreibenS(bExecute := FALSE);
    
    IF NOT FB_SchreibenS.bBusy THEN
        IF FB_SchreibenS.bError THEN
            diSchreibenErrorID := FB_SchreibenS.nErrId;
            bSchreibenError := FB_SchreibenS.bError;
            Step := 10;
        ELSE
            Step := 1;
        END_IF
    END_IF
    

    10:
    (Fehlerfall)
    ;
    END_CASE

    da fehlt jetz natürlich noch bissl was, damit die daten nutzen kannst, aber wenn du das bisschen code verstanden hast, ist es einfach.
    bei fragen einfach fragen!

    mfg speed

    :edit:
    ...iwie is mir die formatierung flöten gegang...

     
  • DaRi - 2011-03-07

    Also ich dachte eher an ein zeichenweises auslesen bis end of line:

    So ungefähr:

    EOL := 16#0A;
    Buffer_i := 0;
    (Auslesen des Buffers bis jeweils EOL erreicht - dann kommt der nächste String)
    WHILE Buffer_i<>EOL DO
    ParaString[n] := Buffer[Buffer_i];
    Buffer_i := Buffer_i+1;
    END_WHILE

    Hier eine kurze Erklärung:
    ParaString[n] ist immer ein zusammengehörender String. In Buffer sind alle Daten gespeichert. Dieser Buffer wird nun zeichenweise ausgelesen, bis EOL erreicht wird. Dann wird die Variable n um 1 erhöht und der nächste String bis zum nächsten EOL wird eingelesen.

    Also so hab ich mir das irgenwie vorgestellt.

     
  • SpeedFreak - 2011-03-08

    hi.
    ich glaube wird reden etwas aneinander vorbei...bzw willst du etwas anderes als ich verstehe
    ich frag einfach mal weiter... wenn du deine zeile einer datei bereits in deinem string "Buffer" drin hast... versteh ich jetzt nicht so richtig, was jetzt noch passieren soll...
    ein solcher string lässt sich doch zeichenweise anschauen, da ein string ja im prinzip ein array aus bytes ist (standard 80byte, es sei denn du deklarierst so: Buffer :string[255])
    warum jetz diesen string nochmal in ein array (ParaString) laden?

    vielleicht kannst zu kurz erklären, was konkret mit den daten passieren soll, damit ich es besser verstehe.

    für zeichenweise aus einer datei lesen gibts bei twincat den FB_FileRead.
    Der FB_FileGets würde automatisch bis zum CRLF (also EOL) auslesen.

    vielleicht reicht dir das ja schon, sonst gerne weiter fragen.

    mfg speed

    ...hab grad deinen post nochmal gelesen... du willst die gesamte datei in "Buffer" laden und erst dann in zeilen zerlegen?
    von welchem datentyp ist "Buffer" dabei?

     
  • Erik Böhm - 2011-03-08

    Servus

    Ich mache das in etwa so:

    dwFileSize := SysFileGetSize(FileName:=strFileName);

    IF dwFileSize < MAX_FILE_SIZE THEN
    diFileRead := SysFileOpen(FileName:=strFileName, Mode:='r');

    IF diFileRead < 1 THEN  (*error: file couldn't be opened *)
        bError  := TRUE;
        wErrorID    := 1;
        RETURN;
    ELSE
        FOR i:=1 TO MAX_FILE_SIZE BY 1 DO   (* Erase Filebuffer *)
            byFileBuffer[i] := 0;
        END_FOR
    
        dwReadSize := SysFileRead(diFileRead, Buffer:=ADR(byFileBuffer), Size:=dwFileSize);
    
        SysFileClose(diFileRead);
        diFileRead  := 0;
        iFilePos        := 0;
    END_IF
    

    ELSE ( Max. Filesize exceeded )
    bError := TRUE;
    wErrorID := 2;
    END_IF

    Gruß
    Erik

     
  • kaspar - 2011-03-19

    Hallo
    Versuchs doch mal mit SipleCSV.pro von Wago.
    Ein Programm das diese Probleme erschlägt.
    Auch für Greeenhörner geeignet.
    Ich habs jedenfals auf die reihe bekommen.
    Gruss Kaspar

     

Log in to post a comment.