Nelle funzioni di uscita formattata su stream (Indicate come printf) la formattazione avviene attraverso segnaposti nella stringa di formato. Per esempio, se un programma vuole stampare l’età di una persona, può presentare l’output con il prefisso “Your age is:“. Per specificare che vogliamo che l’integer dell’età venga stampato dopo il messaggio possiamo usare la forma: “Your age is: %d“. La sintassi del segnaposto di formato è %[Flag][Width][. Accuracy] [Length]Type.
Flag (opzionali) :
# Flag +: mostra sempre il segno del numero
%+d → +10
%+d → -10
# Flag -: allinea il valore a sinistra in un campo di 5 caratteri
%5d → " 42"
%-5d → "42 "
# Flag #: usa la forma alternativa
%#o → 032 # Aggiunge il prefisso ottale
%#x → 0x1a # Aggiunge il prefisso esadecimale minuscolo
%#X → 0X1A # Aggiunge il prefisso esadecimale maiuscolo
%#g → 12.0000 # Mantiene gli zeri finali e il punto decimale
%#.0f → 12. # Mantiene il punto decimale senza cifre decimali
# Flag spazio: inserisce uno spazio prima dei numeri positivi
% d → " 10" # Numero positivo
% d → "-10" # Numero negativo
# Flag 0: riempie con zeri a sinistra
%2d → " 3" # Riempie con uno spazio
%02d → "03" # Riempie con uno zero
%05d → "00042" # Riempie con tre zeri
%05d → "-0042" # Gli zeri vengono dopo il segno
# Combinazione di flag
%+06d → "+00042" # Segno obbligatorio e riempimento con zeri
% 05d → " 0012" # Spazio per il segno positivo e riempimento con zeri
Width (opzionale) mostra l’output di questo segnaposto con spazi finché è largo almeno ”numero” caratteri:
# Larghezza numerica: riserva almeno 5 caratteri, allineando a destra
%5d → " 42"
# Larghezza numerica: se il valore supera la larghezza, non viene troncato
%3d → " 1234"
# Asterisco (*): la larghezza viene specificata dal prossimo argomento
%*d → " 10"
# Asterisco (*): larghezza variabile con un numero negativo
%*d → "10 "
Accuracy (opzionale) o essere:
# Precisione numerica: mostra esattamente 2 cifre decimali
%.2f → "3.14"
# Precisione numerica: arrotonda il valore a 3 cifre decimali
%.3f → "3.142"
# Precisione zero: non mostra cifre decimali
%.0f → "3"
# Precisione sulle stringhe: limita l'output a 3 caratteri
%.3s → "abc"
# Asterisco (*): precisione variabile specificata dal prossimo argomento
%.*f → "3.14"
# Asterisco (*): limita la stringa a 3 caratteri
%.*s → "abc"
Length, (opzionale):
# hh: stampa un intero come signed char o unsigned char
%hhd → -5
%hhu → 250
# h: stampa un intero come short o unsigned short
%hd → -120
%hu → 50000
# l: stampa un intero long o unsigned long
%ld → 123456789L
%lu → 123456789UL
# ll: stampa un intero long long o unsigned long long
%lld → 1234567890123LL
%llu → 1234567890123ULL
# L: stampa un valore long double
%Lf → 3.141593
# z: stampa un intero del tipo corrispondente a size_t
%zu → 1024
# j: stampa un intero del tipo intmax_t o uintmax_t
%jd → -1234567890123
%ju → 1234567890123
# t: stampa un intero del tipo ptrdiff_t
%td → -15
%tu → 15
Type (richiesto):
# d, i: stampa un intero con segno in base decimale
%d → -42
%i → 42
# u: stampa un intero senza segno in base decimale
%u → 42
# f, F: stampa un numero reale in notazione decimale
%f → 3.141593
%F → 3.141593
# e, E: stampa un numero reale in notazione esponenziale
%e → 1.234000e+03
%E → 1.234000E+03
# g, G: sceglie tra notazione decimale ed esponenziale,
# eliminando gli zeri finali superflui
%g → 1234
%G → 1.23E+06
# x, X: stampa un intero senza segno in base esadecimale
%x → 2a
%X → 2A
# o: stampa un intero senza segno in base ottale
%o → 52
# s: stampa una stringa
%s → Ciao mondo
# c: stampa un singolo carattere
%c → A
# p: stampa l'indirizzo rappresentato da un puntatore
%p → 0x7ffe1234
# n: scrive in una variabile il numero di caratteri scritti fino a quel punto; non stampa il valore
%n → (nessun output diretto)
# %: stampa il carattere percentuale
%% → %
# Nota: la sintassi non valida o gli argomenti incompatibili con lo specificatore possono causare comportamento indefinito.
Definire caratteri non stampabili (Solo lato PLC)
La parte di documentazione che segue è valida solo per il lato PLC, e non si applica a pagine web e ePageStudio.
Nella gestione di protocolli di comunicazione quando necessita eseguire l’output di caratteri ascii non stampabili, cioè caratteri con codici inferiori al 16#20 o superiori al 16#7F, occorre anteporre al valore esadecimale del carattere il simbolo $, quindi per il carattere di <STX> 16#02 avremo la definizione ‘$02’, per <ETX> ‘$03’ e così di seguito. Ricordo che alcuni caratteri di controllo come il line feed, codice 16#0A, sia possibile definirli sia come ‘$0A’ che come ‘$l’. Il carriage return, codice 16#0D, è possibile definirlo sia come ‘$0D’ che come ‘$r’, di seguito un elenco:
- $a: Bell (speaker beeps)
- $b: Backspace (non-erase)
- $f: Form feed/clear screen
- $l: Line feed (Esempio ‘next $l line’)
- $n: New line
- $p: New page
- $r: Carriage return (Esempio ‘Hello$r’)
- $t: Tab
- $v: Vertical tab
- $$: Dollar sign (Esempio ‘I paid $$5 for this’)
- $’: Single quote (Esempio ‘Enter $’Y$’ for YES’)
- $”: Double quote
- $hh: Hexadecimal character code hh (Esempio ‘ABCD=$41$42$43$44’)
Esempi
Come utilizzare gli esempi.
Per meglio comprendere come definire il segnaposto, riportiamo alcuni esempi.
LogicLab (Ptp116, ST_HowToUsePrintf)
PROGRAM ST_HowToUsePrintf
VAR
Nr : INT; (* Number of returned chars *)
FPVar : UDINT; (* Fixed point variable *)
LIVar : LINT; (* Signed long integer variable *)
ULVar : ULINT; (* Unsigned long integer variable *)
FLVar : REAL; (* Floating point variable *)
LRVar : LREAL; (* Long real variable *)
SVar : STRING[ 32 ]; (* String variable *)
SOut : STRING[ 32 ]; (* Output string *)
END_VAR
// *****************************************************************************
// PROGRAM "ST_HowToUsePrintf"
// *****************************************************************************
// Here some examples how to use the format field in printf function.
// -----------------------------------------------------------------------------
// Fixed point variable print.
FPVar:=12; //Fixed point variable
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%d'), UDINT_TYPE, ADR(FPVar)); //Nr:2, SOut:"12"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%1d'), UDINT_TYPE, ADR(FPVar)); //Nr:2, SOut:"12"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%4d'), UDINT_TYPE, ADR(FPVar)); //Nr:4, SOut:" 12"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('% 4d'), UDINT_TYPE, ADR(FPVar)); //Nr:4, SOut:" 12"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%-4d'), UDINT_TYPE, ADR(FPVar)); //Nr:4, SOut:"12 "
// Floating point variable print.
FLVar:=12.543; //Floating point variable
LRVar:=LREAL#12.543; //Long real variable
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%f'), REAL_TYPE, ADR(FLVar)); //Nr:9, SOut:"12.543000"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%.4f'), REAL_TYPE, ADR(FLVar)); //Nr:7, SOut:"'12.5430"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%4.2f'), REAL_TYPE, ADR(FLVar)); //Nr:5, SOut:"12.54"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%5.2f'), REAL_TYPE, ADR(FLVar)); //Nr:5, SOut:"12.54"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%8.1f'), REAL_TYPE, ADR(FLVar)); //Nr:8, SOut:" 12.5"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%-8.1f'), REAL_TYPE, ADR(FLVar)); //Nr:8, SOut:" 12.5"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%.16lf'), LREAL_TYPE, ADR(LRVar)); //Nr:19, SOut:"'12.5430002212524414"
// Long integer variable print.
LIVar:=-1234567890123456789; //Signed long integer variable
ULVar:=12345678901234567890; //Unsigned long integer variable
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%lld'), LINT_TYPE, ADR(LIVar)); //Nr:20, SOut:"-1234567890123456789"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%llu'), ULINT_TYPE, ADR(ULVar)); //Nr:20, SOut:"12345678901234567890"
// String variable print.
SVar:='Hello!'; //String variable
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%s'), STRING_TYPE, ADR(SVar)); //Nr:6, SOut:"Hello!"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%16s'), STRING_TYPE, ADR(SVar)); //Nr:16, SOut:" Hello!"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%-16s'), STRING_TYPE, ADR(SVar)); //Nr:16, SOut:"Hello! "
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%.3s'), STRING_TYPE, ADR(SVar)); //Nr:3, SOut:"Hel"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%16.3s'), STRING_TYPE, ADR(SVar)); //Nr:16, SOut:" Hel"
Nr:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%-16.3s'), STRING_TYPE, ADR(SVar)); //Nr:16, SOut:"Hel "
// [End of file]