SysStrFind, string find

List

Questa pagina fa parte del Manuale Programmazione IEC 61131-3. Vai all indice.

Questa funzione cerca la stringa Needle in Haystack , la ricerca è effettuata in base alla definizione di Mode. Se la stringa è trovata viene ritornato il puntatore all’indirizzo di Haystack dove si trova.

In base alla definizione di Mode può essere ritornato l’indirizzo del primo carattere coincidente oppure l’indirizzo del carattere successivo all’ultimo carattere coincidente. Se stringa non trovata o errore viene ritornato NULL.

Information Circle

Funzione

CODESYS: eCDSXUnified12Lib

LogicLab: eLLabXUnified12Lib

Descrizione

Haystack (@STRING) Pointer alla stringa dove effettuare la ricerca.
Needle (@STRING) Pointer alla stringa da ricercare.
Mode (DWORD) Definizione modo in cui effettuare la ricerca (Vedi definizione).

La funzione ritorna un (@STRING) indirizzo di Haystack dove Needle è stata trovata, eNULL se non trovata.

Immagine funzione SysStrFind

Esempi

Come utilizzare gli esempi.
Viene eseguita la ricerca della stringa ‘World‘ nella stringa presente in Str che è valorizzata con ‘HelloWorld!, helloworld!‘ con diversi modi di ricerca. Dal pointer ritornato viene sottratto l’indirizzo di allocazione di Str in modo da ottenere la posizione relativa della stringa trovata nella stringa di ricerca. Vediamo i vari risultati.

  • Position[0]: 5, La ricerca parte dall’inizio e ritorna la posizione di inizio della prima occorrenza.
  • Position[1]: 10, La ricerca parte dall’inizio e ritorna la posizione successiva alla fine della prima occorrenza.
  • Position[2]: 18, La ricerca parte dalla fine e ritorna la posizione di inizio della prima occorrenza.
  • Position[3]: 23, La ricerca parte dalla fine e ritorna la posizione successiva alla fine della prima occorrenza.
LogicLab (Ptp116, ST_SysStrFind)
PROGRAM ST_SysStrFind
VAR
    Position : ARRAY[ 0..3 ] OF UDINT; (* Found position *)
    Str : STRING[ 32 ] := 'HelloWorld!, helloworld!'; (* Source string *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_SysStrFind"
// *****************************************************************************
// Some find examples.
// -----------------------------------------------------------------------------

    Position[0]:=TO_UDINT(SysStrFind(ADR(Str),ADR('World'), FIND_DEFAULT))-TO_UDINT(ADR(Str));
    Position[1]:=TO_UDINT(SysStrFind(ADR(Str),ADR('World'), FIND_GET_END))-TO_UDINT(ADR(Str));
    Position[2]:=TO_UDINT(SysStrFind(ADR(Str),ADR('World'), FIND_FROM_END OR FIND_NO_CASE))-TO_UDINT(ADR(Str));
    Position[3]:=TO_UDINT(SysStrFind(ADR(Str),ADR('World'), FIND_FROM_END OR FIND_GET_END OR FIND_NO_CASE))-TO_UDINT(ADR(Str));

// [End of file]
CODESYS (Ptp161, ST_SysStrFind)
PROGRAM ST_SysStrFind
VAR
    Position : ARRAY[ 0..3 ] OF UDINT; //Found position
    Str : STRING[ 32 ] := 'HelloWorld!, helloworld!'; //Source string
END_VAR

// *****************************************************************************
// PROGRAM "ST_SysStrFind"
// *****************************************************************************
// Some find examples.
// -----------------------------------------------------------------------------

// *****************************************************************************
// PROGRAM "ST_SysStrFind"
// *****************************************************************************
// Some find examples.
// -----------------------------------------------------------------------------

    Position[0]:=SysStrFind(ADR(Str),ADR('World'), FIND_MODE.FIND_DEFAULT)-ADR(Str);
    Position[1]:=SysStrFind(ADR(Str),ADR('World'), FIND_MODE.FIND_GET_END)-ADR(Str);
    Position[2]:=SysStrFind(ADR(Str),ADR('World'), FIND_MODE.FIND_FROM_END OR FIND_MODE.FIND_NO_CASE)-ADR(Str);
    Position[3]:=SysStrFind(ADR(Str),ADR('World'), FIND_MODE.FIND_FROM_END OR FIND_MODE.FIND_GET_END OR FIND_MODE.FIND_NO_CASE)-ADR(Str);

// [End of file]

Programma “TagFinder”

Un semplice programma che esegue la ricerca all’interno di un file CSV del codice di una TAG. Attivando Find, viene eseguita la ricerca del tag definito in TagToFind nel file di tipo CSV definito in Filename. Per eseguire la ricerca vengono lette una alla volte le varie righe del file, in ogni riga viene ricercata la colonna che contiene indicazione del tag da cercare e confrontato il valore con quello ricercato. Si esce quando viene trovato il tag oppure a fine file.

Se il tag è stato trovato Found e a TRUE, in RCount viene ritornata la riga in cui il codice è stato trovato ed in RBuffer si trova il contenuto della riga. Per velocizzare la ricerca senza penalizzare il tempo di esecuzione sono ricercate il numero di righe definite in RowsAtLoop per ogni loop di esecuzione. A titolo di rifeferimento con un file CSV del tipo indicato che contiene 10000 righe su di un sistema Cortex M7 per trovare il tag nell’ultima riga occorrono circa 970 mS.

LogicLab (Ptp181, TagFinder)
PROGRAM TagFinder
VAR
    Find : BOOL; (* Find command *)
    Found : BOOL; (* Tag found *)
    Done : BOOL; (* Execution done *)
    i : UDINT; (* Auxiliary var *)
    Fp : eFILEP; (* File pointer *)
    FPos : DINT; (* File position *)
    RCount : UDINT; (* Row counter *)
    CaseNr : USINT; (* Program case *)
    LRCount : UDINT; (* Loop row counter *)
    ENumber : USINT; (* Error number *)
    RowsAtLoop : UDINT; (* Rows checked every loop *)
    Filename : @STRING; (* Path and name of file *)
    TagToFind : @STRING; (* Tag to find *)
    RBuffer : STRING[ 64 ]; (* Row buffer *)
    TagData : STRING[ 16 ]; (* Tag cell data *)
    APtr : ARRAY[0..1] OF @STRING; (* Auxiliary pointer *)
    TimeBf : ARRAY[0..1] OF UDINT; (* Time buffer (mS) *)
    FTime : ARRAY[0..1] OF REAL; (* Find time (S) *)
END_VAR

// *****************************************************************************
// PROGRAM "TagFinder"
// *****************************************************************************
// This program finds a Tag on a CSV file. To test the program create the
// "Tags.csv" file by copying the following lines.
//
// Barcode;Tag;Check;Auth-ID
// Z0001;9A7611D3000000;true;1
// Z0032;9B1FDD53000000;false;1
// Z0033;BBCFDD53000000;true;1
// Z0034;1338DD53000000;false;1
// Z0035;F7E8DC53000000;false;1
//
// Each line must terminate with  characters.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATION
    // -------------------------------------------------------------------------
    // Here the search parameters are set.

    IF (SysFirstLoop) THEN
        Filename:=ADR('D:/Tags.csv'); //Path and name of file
        TagToFind:=ADR('1338DD53000000'); //Tag to find
        RowsAtLoop:=100; //Rows checked every loop
    END_IF;

    // -------------------------------------------------------------------------
    // CHECK RESULTS
    // -------------------------------------------------------------------------
    // Check if the tag is found or an error is occurred.

    IF (Done OR (ENumber <> 0)) THEN
        IF (SysFIsOpen(Fp)) THEN Fp:=Sysfclose(Fp); END_IF;
        IF (CaseNr <> 0) THEN
            FTime[1]:=TO_REAL(SysTimeGetMs()-TimeBf[0])/1000.0; //Find time (S)
            CaseNr:=0; //Program case
        END_IF;
    END_IF;
 
    // -------------------------------------------------------------------------
    // PROGRAM CASES MANAGEMENT
    // -------------------------------------------------------------------------
    // Manage the program cases.

    WHILE (TRUE) DO CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // WAITING COMMAND
        // ---------------------------------------------------------------------
        // Wait the command.

        0:
        IF NOT(Find) THEN RETURN; END_IF;
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Initialize all variables.

        1:
        Find:=FALSE; //Find command
        Found:=FALSE; //Tag found
        Done:=FALSE; //Execution done
        FPos:=0; //File position
        RCount:=0; //Row counter
        ENumber:=0; //Error number
        TimeBf[0]:=SysTimeGetMs(); //Full searching time reference

        // Open the data file.

        Fp:=SysFfopen(Filename, ADR('r')); //File pointer
        IF NOT(SysFIsOpen(Fp)) THEN ENumber:=10; RETURN; END_IF;
        CaseNr:=10; //Program case

        // ---------------------------------------------------------------------
        //  SEARCHING FOR THE NUMBER OF LOOP ROWS
        // ---------------------------------------------------------------------
        // Initialize the search.

        10:
        LRCount:=0; //Loop row counter
        TimeBf[1]:=SysTimeGetMs(); //Loop rows time reference
        CaseNr:=20; //Program case
        
        // ---------------------------------------------------------------------
        // EXECUTE SEARCH
        // ---------------------------------------------------------------------
        // Set position to read on file.

        20:
        IF (Sysfseek(Fp, FPos, ID_SEEK_SET) = eEOF) THEN ENumber:=20; RETURN; END_IF;

        // Read a row buffer of data. The buffer MUST BE long enough to contain
        // a entire row of CSV file data. If not character read the search is
        // finished.

        i:=Sysfread(ADR(RBuffer), 1, TO_INT(SIZEOF(RBuffer)), Fp);
        IF (i < 1) THEN Done:=TRUE; RETURN; END_IF;

        // The row MUST be terminated with  otherwise error.

        APtr[0]:=SysStrFind(ADR(RBuffer), ADR('$r$n'), FIND_GET_END);
        IF (APtr[0] = eNULL) THEN ENumber:=30; RETURN; END_IF;

        // Terminate the row buffer with a zero character and force the disk
        // position after line end.

        i:=eSetBYTE(APtr[0], 16#00); //Zero ternminator
        FPos:=FPos+TO_DINT(APtr[0]-ADR(RBuffer)); //File position
        LRCount:=LRCount+1; //Loop row counter
        RCount:=RCount+1; //Row counter
        
        // The first row contains column descriptions so it's skipped.

        IF (RCount = 1) THEN CaseNr:=20; ELSE CaseNr:=CaseNr+1; END_IF;        

        // ---------------------------------------------------------------------
        // Arrive here with the entire line on row buffer.
        // First find the ";" that identify the "Tag" cell begin.
        
        21:
        APtr[0]:=SysStrFind(ADR(RBuffer), ADR(';'), FIND_GET_END); //Auxiliary pointer
        IF (APtr[0] = eNULL) THEN ENumber:=40; RETURN; END_IF;

        // Now find the ";" that identify the "Tag" cell end.

        APtr[1]:=SysStrFind(APtr[0], ADR(';'), FIND_DEFAULT); //Auxiliary pointer
        IF (APtr[1] = eNULL) THEN ENumber:=50; RETURN; END_IF;

        // Now move the "Tag" cell data.

        i:=Sysmemmove(ADR(TagData), APtr[0], TO_UDINT(APtr[1]-APtr[0]));

          // Now compare data with desired one, stop search if found.

        IF (SysStrFind(ADR(TagData), TagToFind, FIND_DEFAULT) <> eNULL) THEN
            Found:=TRUE; //Tag found
            Done:=TRUE; //Execution done
            RETURN;
        END_IF;

        // The Tag is not found so process a new row.
        // To avoid a long loop time, terminate after a defined number of row
        // and calculate the partial time.

        CaseNr:=20; //Program case
        IF (LRCount >= RowsAtLoop) THEN
            FTime[0]:=TO_REAL(SysTimeGetMs()-TimeBf[1])/1000.0; //Find time (S)
            CaseNr:=10; //Program case
            RETURN;
        END_IF;
    END_CASE; END_WHILE;

// [End of file]
Was this article helpful?