Tutorial StringFormat - Warum es guter Stil ist :-)

    • Offizieller Beitrag

    Hallo,

    Heute mal ein kleines Anliegen von mir.
    Eine der Funktionen, die man am Anfang nicht versteht und die sich dann später als sehr nützlich herausstellen :).

    Es geht um die Funktion

    [autoit]

    StringFormat

    [/autoit]

    .

    Die Hilfe sagt dazu:


    (Online: https://autoit.de/dokumentation_…tringFormat.htm)

    Was tut die Funktion nun konkret?

    Nehmen wir an, wir haben die folgende Ausgabe, die in einer MsgBox oder sonst irgendwo im Programm erscheint:

    [autoit]

    "Es wurden " & $i & " Fehler gefunden, die auf die Funktion " & $funktionsname & " zurückzuführen waren"

    [/autoit]


    Dieses Konstrukt hat mehrere Nachteile:
    1. Schlechte Lesbarkeit
    2. Anfällige Setzung der Spezialzeichen " und &
    3. Schlechte Übersetzbarkeit

    Der dritte Punkt wird klar, wenn wir es ins Englische bringen:

    [autoit]

    "The function " & $funktionsname & " caused " & $i & " errors."

    [/autoit]


    Die Reihenfolge der Parameter kann sich ändern, die Teilzeichenketten enthalten in aller Regel verschiedene Satzanteile und es ist wesentlich schwerer aus kleinen Fetzen korrekte Übersetzungen zu bauen, wenn man nur die Teilstrings bekommt.

    Die Funktion StringFormat hilft uns gegen alle drei Nachteile von oben. Das Konstrukt sieht damit wie folgt aus:

    [autoit]

    StringFormat("Es wurden %i Fehler gefunden, die auf die Funktion %s zurückzuführen waren", $i, $funktionsname)

    [/autoit]


    Dabei entsteht genau die gleiche Ausgabe wie vorher allerdings besser wartbar. Der Text ist zusammenhängend und es werden nur an die kodierten Stellen die Variablen eingefügt.
    Eine Konstruktion wie

    [autoit]

    StringFormat('Der Satz "%s" war korrekt.', $satz)

    [/autoit]


    werden deutlich vereinfacht, weil die Setzung der Anführungsstriche übersichtlicher wird.

    Die Variablen (beginnend mit %, %% für ein wirkliches Prozentzeichen) werden in der Reihenfolge ihres Auftretens mit den Variablenwerten der weiteren Parameter ersetzt.


    Ein weiteres Anwendungsgebiet sind Umformatierungen von Zahlen, z.B.

    [autoit]

    StringFormat("Du lagst zu %.2f %% richtig.", 4.643)

    [/autoit]

    .

    Weitere Beispiele dazu gibt es in der Hilfe, im Wesentlichen bestimmt die 2 die Zahl der Nachkommastellen und %03.2f führt zu genau 3 Stellen vor dem Komma, die mit Nullen aufgefüllt werden, falls nötig.

    peethebee

  • also ich gehör definitiv zu den oberen leuten, hab die funktion nicht gekannt.

    werd sie aber mal ausprobieren und dann auch verwenden.

    Canyon

  • Ich habe eine praktische Ergänzung dazu: Wenn man mehrzeilige Texte in z.B. eine Ini speichern will, kann man die Funktion einfach dazu missbrauchen, solche Strings aus ihrer einzeiligen Darstellung zu dekodieren. (Einfach die zusätzlichen Parameter nicht verwenden ;) ) Zum Kodieren habe ich eine Funktion geschreiben:

    Spoiler anzeigen
    [autoit]

    $text = "test \r\n" & @CRLF & ":)"
    $encoded = _StringEscape($text)

    [/autoit] [autoit][/autoit] [autoit]

    $format = StringFormat($text)
    $encformat = StringFormat($encoded)
    MsgBox(0, '', "## Originaltext: ##" & @CRLF & $text & @CRLF & "## nach _StringEscape ##" & @CRLF & $encoded & @CRLF & "## StringFormat vor _StringEscape ##" & @CRLF & $format & @CRLF & "## StringFormat nach _StringEscape ##" & @CRLF & $encformat & @CRLF & "#######################" )

    [/autoit] [autoit][/autoit] [autoit]

    ; Prog@ndy
    Func _StringEscape($String)
    Local $escaping[5][2] = [ ['%','%%'], ['\','\\'], [@CR,'\r'], [@LF, '\n'], [@TAB,'\t'] ]
    For $i = 0 To UBound($escaping)-1
    $String = StringReplace($String,$escaping[$i][0],$escaping[$i][1]);,0,1)
    Next
    Return $String
    EndFunc

    [/autoit]
  • Juhu! C lebt!
    freut mich sowas in autoit zu sehen, werd ich künftig benutzen =P :thumbup:

  • ähnlich zu der C sprintf() Funktion


    Ich kenn mich mit C ja noch nicht so gut aus (fange gerade damit an), aber heißt es nicht:

    Code
    pfintf()

    ?

    MfG. tobi_girst

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »tobi_girst« (Morgen, 25:63)

  • Kann mir jemand erklären, wie ich den StringFormat() dazu verwenden, von einen String nur Reele-Zahlen+Rechenzeichen auszugeben?

  • Was sind denn "Reele-Zahlen+Rechenzeichen".
    Reele von Schaltrelai? Da gibt es nämlich zahlreiche. Welche die nur zwei Stellungen haben und welche mit mehr als zwei Stellungen.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Hallo Alina,

    hier die Anwort auf deine "Relais-Zahlen" Frage

    @freakisch Stringformat gibt das aus, was du ihm anweist, Rechenzeichen sind als Formatierung nicht möglich, aber die Ausgabe eines negtiven Vorzeichens. Du kannst aber den Operator "&" benutzen um Teilstrings zusammenzusfügen, die du z.B. mit RegExp erzeugt hast, lies dazu evtl. das Tutorial von BugFix

    mfg (Auto)Bert

    2 Mal editiert, zuletzt von AutoBert (18. Mai 2009 um 00:31)

  • ...
    3. Schlechte Übersetzbarkeit
    ...
    Die Reihenfolge der Parameter kann sich ändern, die Teilzeichenketten enthalten in aller Regel verschiedene Satzanteile und es ist wesentlich schwerer aus kleinen Fetzen korrekte Übersetzungen zu bauen, wenn man nur die Teilstrings bekommt.
    ...


    Naja, da ändert die AutoIt Funktion StringFormat je leider auch nichts dran:

    [autoit]

    Global $i = 5, $funktionsname = '_example'
    Global $Lang_DE = "Es wurden %i Fehler gefunden, die auf die Funktion %s zurückzuführen waren"
    Global $Lang_EN = "The function %s caused %i errors."

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite(StringFormat($Lang_EN, $i, $funktionsname))

    [/autoit]


    Hier fehlt mir eindeutig die Möglichkeit die Reihenfolge der Platzhalter angeben zu können :(
    Wie in php zb:

    PHP
    $anzahl = 5;
    $ort    = 'Baum';
    
    
    $format = 'Der %2$s enthält %1$d Affen';
    printf($format, $anzahl, $ort);
    
    
    $format = 'Der %2$s enthält %1$d Affen. %1$d Affen sind ziemlich viel für einen %2$s.';
    printf($format, $anzahl, $ort);


    Oder hab ich da was übersehen, und das ist mit der AutoIt Funktion StringFormat auch möglich?

  • Zitat von peethebee

    2. Anfällige Setzung der Spezialzeichen " und &

    Dafür gibts ja sowas:

    [autoit]

    Opt("ExpandVarStrings", 1)
    $iAnzahl = 5
    ConsoleWrite("!> Es wurden $iAnzahl$ Fehler gefunden!" & @lf)

    [/autoit]
    Zitat von Taz77

    Oder hab ich da was übersehen, und das ist mit der AutoIt Funktion StringFormat auch möglich?

    Dazu der ehem. AutoIt-Entwickler Valik:

    Zitat

    This looks absolutely retarded. As if StringFormat() isn't confusing enough, now you want to add unnecessary complexity to format specifiers? Pass the correct number of parameters in the correct order and the problem is solved. The design PHP is using solves a minor inconvenience with some very ugly syntax and I don't see any value in adding it to AutoIt.

    Einmal editiert, zuletzt von minx (24. April 2013 um 00:06)

  • schade eigentlich.

    PS: Danke für die Fixe Antwort, hatte dazu leider nichts gefunden.

    Edit:
    Ich hab mir mal eine Funktion erstellst, die Parameter in Strings ersetzt. Kann ggf. ganz nützlich sein, gerade in Bezug auf die Übersetzbarkeit ;)

    Funktion:

    [autoit]

    Func _StringSetParameter($sFormat, $1='', $2='', $3='', $4='', $5='', $6='', $7='', $8='', $9='', $10='')
    Return Execute("'" & StringRegExpReplace(StringReplace($sFormat, "'", "''", 0, 2), "%(\d{1,10})", "'&$\1&'") & "'")
    EndFunc

    [/autoit]

    Beispiel:

    [autoit]

    Global $Fehler = 5, $FunktionsName = '_example'
    Global $Lang_DE = 'Es wurden %1 Fehler gefunden, die auf die Funktion "%2" zurückzuführen waren'
    Global $Lang_EN = 'The function "%2" caused %1 errors.'

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite(_StringSetParameter($Lang_EN, $Fehler, $FunktionsName) & @CRLF)
    ConsoleWrite(_StringSetParameter($Lang_DE, $Fehler, $FunktionsName))

    [/autoit]

    Einmal editiert, zuletzt von Taz77 (24. April 2013 um 08:56) aus folgendem Grund: Funktion und Beispiel hinzugefügt