Vai al contenuto

Copiare un carattere da una stringa in una variabile

Home Forum Programmazione IEC 61131 (LogicLab) Copiare un carattere da una stringa in una variabile

Stai visualizzando 8 post - dal 1 a 8 (di 8 totali)
  • Autore
    Post
  • #34933
    Anonimo
    Inattivo

    Sulla Cpu SlimLine, non riesco a fare questa operazione:

    Data una stringa ‘ABCDEFGHIL’ nella variabile DString di 10 caratteri, vorrei estrarre l’iesimo elemento e copiarlo dopo una conversione in ASCII in un byte. Avete qualche dritta in proposito ?

    #36596
    Sergio Bertana
    Amministratore del forum

    La soluzione piu semplice è utilizzare un puntatore. Ti allego la stampa di un programma in ST che effettua quello di cui hai bisogno. Download programma sorgente (Funziona su emulatore PLC).

    VAR
        DString : STRING[ 10 ] := ‘ABCDEFGHIL’; (* Data string *)
        Ch : ARRAY[ 0..9 ] OF USINT; (* Character *)
        ChPtr : @USINT; (* Character pointer *)
    END_VAR

    ChPtr:=ADR(DString); (* Punto origine stringa *)
    Ch[0]:=@ChPtr+0; (* Leggo carattere in posizione 0 ‘A’ *)
    Ch[1]:=@ChPtr+1; (* Leggo carattere in posizione 1 ‘B’ *)

    ChPtr:=ADR(DString)+2; (* Punto carattere in stringa *)
    Ch[2]:=@ChPtr; (* Leggo carattere in posizione 2 ‘C’ *)

    #52904
    Marco
    Partecipante

    Non funziona più questa soluzione su cpu MPS054? Non riesco a far funzionare questo esempio.

    #52910
    Sergio Bertana
    Amministratore del forum

    L’esempio funziona anche su MPS054, non capisco le tue difficoltà nel farlo funzionare.

    Ho comunque provveduto ad importare il progetto String con l’ultima versione di LogicLab, prova ad eseguire il download di questo esempio. Il funzionamento del programma si può testare anche utilizzando l’ambiente di simulazione SimuLab integrato in LogicLab. Ecco lo screenshot del programma in simulazione.

    #53005
    Marco
    Partecipante

    Non riesco ad allegare l’immagine dello screenshot che intendo inserire ma se vario la stringa esempio inserisco “elsistmp” ovviamente allunganto la codifica a più caratteri il risultato dei puntatori non corrispponde ai carattei inseriti

    PROGRAM ST
    VAR
    DString : STRING[ 10 ] := 'elsistmp'; (* Data string *)
    Ch : ARRAY[0..9] OF USINT; (* Character *)
    ChPtr : @USINT; (* Character pointer *)
    END_VAR 
    
    (* -------------------------------------------------------------------------- *)
    (* ESTRAZIONE CARATTERE DA STRINGA *)
    (* -------------------------------------------------------------------------- *)
    
    ChPtr:=ADR(DString); (* Punto origine stringa *)
    Ch[0]:=@ChPtr+0; (* Leggo carattere in posizione 0 *)
    Ch[1]:=@ChPtr+1; (* Leggo carattere in posizione 1 *)
    Ch[2]:=@ChPtr+2; (* Leggo carattere in posizione 2 *)
    Ch[3]:=@ChPtr+3; (* Leggo carattere in posizione 3 *)
    Ch[4]:=@ChPtr+4; (* Leggo carattere in posizione 4 *)
    Ch[5]:=@ChPtr+5; (* Leggo carattere in posizione 5 *)
    Ch[6]:=@ChPtr+6; (* Leggo carattere in posizione 6 *)
    Ch[7]:=@ChPtr+7; (* Leggo carattere in posizione 7 *)
    
    (* [End of file] *)

    risultato :
    Ch[0] 101
    Ch[1] 102
    Ch[2] 103
    Ch[3] 104
    Ch[4] 105
    Ch[5] 106
    Ch[6] 107
    Ch[7] 108

    … probabile che non abbia capito io quale codifica venga utilizzata per i caratteri, dall’esempio con “ABCD..” risultava 65,66,67…  perchè ‘elsistmp’ risulta quanto sopra riportato?

    Dove sbaglio?

    #53018
    Sergio Bertana
    Amministratore del forum

    L’errore l’ho commesso io nel farti l’esempio (Lavoro anche con il linguaggio C ed a volte mi prendo libertà che in ST non sono possibili).

    Avendo usato la stringa di esempio “ABCD…” i codici ascii dei vari caratteri sono consecutivi e non mi sono accorto che la scrittura del programma era errata… chiedo venia… Ecco come puoi scrivere:

    DString:='elsistmp';
    ChPtr:=ADR(DString); //Character pointer
    Ch[0]:=@ChPtr; //Leggo carattere in posizione 0
    ChPtr:=ChPtr+1; //Character pointer
    Ch[1]:=@ChPtr; //Leggo carattere in posizione 1
    
    ChPtr:=ADR(DString)+5; //Character pointer
    Ch[5]:=@ChPtr; //Leggo carattere in posizione 5
    #81125
    Paolo
    Partecipante

    Buongiorno, con ultima versione di LogicLab ( 10 , lib 040 ), l’esempio non funziona, mi restituisce errore in fase di compilazione :

    error G0271:  ChPtr => Invalid operation on different pointed types

    Ecco il codice :

    VAR
        DString : STRING[ 10 ];    (* Data string *)
        Ch : ARRAY[0..9] OF USINT;    (* Character *)
        ChPtr : @USINT;    (* Character pointer *)
    END_VAR
    
    DString:='elsistmp';
    ChPtr:=ADR(DString); //Character pointer
    Ch[0]:=@ChPtr; //Leggo carattere in posizione 0
    
    ChPtr:=ChPtr+1; //Character pointer
    Ch[1]:=@ChPtr; //Leggo carattere in posizione 1

    Grazie…

    #81146
    Sergio Bertana
    Amministratore del forum

    Il problema è nell’aver settato l’opzione Strict pointer check nel menù Project->Options->Code generation. Questa opzione che per sicurezza viene settata di default effetua il controllo sul tipo di pointer segnalando errore quando si valorizza un pointer con un indirizzo di variabile diversa dal suo tipo.

    La variabile ChPtr definita come pointer ad USINT la valorizzi con l’indirizzo di una stringa.

    ChPtr:=ADR(DString); //Character pointer

    Per soluzionare puoi disabilitare lo Strict pointer check, ma la soluzione più corretta è utilizzare eTO_POINTER nel modo:

    ChPtr:=eTO_POINTER(ADR(DString)); //Character pointer

    eTO_POINTER() trasforma l’indirizzo in un puntatore a void ePVOID che essendo un tipo diremmo oggi “fluido” viene accettato da tutte le assegnazioni.

Stai visualizzando 8 post - dal 1 a 8 (di 8 totali)
  • Devi essere connesso per rispondere a questo topic.