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.
Approfondimenti
- In questo topic un programma che esegue il parsing di una stringa.
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.

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 *)
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:=FClose(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.
IF (Sysfread(ADR(RBuffer), 1, TO_INT(SIZEOF(RBuffer)), Fp) < 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.
eTO_JUNK(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.
eTO_JUNK(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]