Was ist Zeichencodierung?
Ein Computer kennt nur Zahlen (Bits und Bytes). Damit Zeichen wie «A», «ä» oder «€» gespeichert werden können, braucht man eine Codierungstabelle – sie ordnet jedem Zeichen eine Zahl zu.
String vs. WString in Siemens SCL
String
1 Zeichen = 1 Byte (8 Bit)
Codierung: ISO 8859-1
Zeichenvorrat: 0–255 (256 Zeichen)
→ Lateinische Zeichen, Umlaute
Maximallänge: 254 Zeichen
Speicher: 2 Header-Bytes + max. Länge Bytes
Literal: 'Text'
WString
1 Zeichen = 1 Wort (2 Bytes) (16 Bit)
Codierung: UTF-16 (Unicode)
Zeichenvorrat: 0–65535
→ Alle Weltsprachen
Maximallänge: 16382 Zeichen
Speicher: 4 Header-Bytes + max. Länge × 2 Bytes
Literal: WString#'Text'
WString#.Übersichtstabelle
| Eigenschaft | String | WString |
|---|---|---|
| Byte pro Zeichen | 1 Byte | 2 Bytes (1 Wort) |
| Codierung | ISO 8859-1 / ASCII | UTF-16 (Unicode) |
| Zeichenbereich | 0x00 – 0xFF | 0x0000 – 0xFFFF |
| Max. Länge (Default) | 254 Zeichen | 16382 Zeichen |
| Header-Bytes | 2 (max. + akt. Länge) | 4 (je 2 Bytes als WORD) |
| Speicher gesamt | fest: 2 + max. Länge Bytes | fest: 4 + max. Länge × 2 Bytes |
| Literal in SCL | 'Hallo' | WString#'Hallo' |
| Umlaute ä, ö, ü im Literal | ⚠ Übersetzungswarnung (Code > 127) | ✓ keine Warnung |
| Zeichen > 0xFF (z.B. €) | ✗ nicht möglich | ✓ |
| S7-1200 / S7-1500 | ✓ | ✓ |
Statischer Speicher – kein dynamisches Wachstum
Der Speicherbedarf im Datenbaustein ist immer fest und richtet sich nach der deklarierten Maximallänge – unabhängig vom aktuellen Inhalt.
String[100] reserviert immer 102 Bytes (2 Header + 100 Datenbytes) – egal ob der String leer ist oder 100 Zeichen enthält. Nur der Header-Wert «aktuelle Länge» ändert sich.String[10]
= 2 + 10 = 12 Bytes (immer)
WString[10]
= 4 + 10×2 = 24 Bytes (immer)
Speicherlayout – interaktive Visualisierung
Gib einen Text und eine Maximallänge ein. Der gesamte reservierte Bereich ist immer gleich gross – nur der Header-Wert «aktuelle Länge» passt sich an.
ASCII-Zeichentabelle (0–127)
Die Codes 0–127 sind in ASCII, ISO 8859-1 und UTF-16 identisch.
| Dez. | Hex | Zeichen | Bedeutung |
|---|
'A' → Byte mit Wert 65 = 0x41Erweiterter ASCII – Bereich 128–255 (ISO 8859-1)
ä, ö, ü) erzeugen beim Übersetzen eine Warnung – die Darstellung hängt von der Windows-Codepage ab.Empfehlung: Hex-Escape verwenden:
'$E4' statt 'ä'. Beim WString gibt es diese Warnung nicht.| Dez. | Hex | Zeichen | String-Literal (sicher) | Bemerkung |
|---|---|---|---|---|
| 196 | 0xC4 | Ä | '$C4' | Grosses Ä |
| 214 | 0xD6 | Ö | '$D6' | Grosses Ö |
| 220 | 0xDC | Ü | '$DC' | Grosses Ü |
| 228 | 0xE4 | ä | '$E4' | Kleines ä |
| 246 | 0xF6 | ö | '$F6' | Kleines ö |
| 252 | 0xFC | ü | '$FC' | Kleines ü |
| 223 | 0xDF | ß | '$DF' | Eszett |
| U+20AC | € | ✗ nicht möglich | Nur im WString | |
Unicode – der universelle Zeichensatz
Unicode ordnet jedem Zeichen der Welt eine eindeutige Nummer zu (sog. Code Point, geschrieben U+XXXX).
| Zeichen | Code Point | Hex | Im WString (2 Bytes, Little Endian) |
|---|---|---|---|
| A | 65 | U+0041 | 41 00 |
| ä | 228 | U+00E4 | E4 00 |
| € | 8364 | U+20AC | AC 20 |
| 中 | 20013 | U+4E2D | 2D 4E |
00.Unicode-Blöcke (Auswahl)
Vergleich bei Sonderzeichen
| Text | String | WString |
|---|---|---|
| «Hi» | 2 Datenbytes | 4 Datenbytes |
| «ä» sicher angeben | '$E4' → kein Warning | WString#'ä' → kein Warning |
| «€» (U+20AC) | ✗ nicht darstellbar | AC 20 |
| «中» (U+4E2D) | ✗ nicht darstellbar | 2D 4E |
SCL-Beispiele: String und WString
Deklaration
VAR s1 : String; // max. 254 Zeichen (Standard) s2 : String[50]; // max. 50 Zeichen, reserviert 52 Bytes ws1 : WString; // max. 16382 Zeichen ws2 : WString[50]; // max. 50 Zeichen, reserviert 104 Bytes zeichen : Char; laenge : Int; END_VAR
WString# eingeleitet werden. Ein 'Text' ohne Präfix wird als String interpretiert.Zuweisung
// String s1 := 'Hallo Welt'; s2 := 'Temperatur: 23.5 Grad'; // WString: Schluessel WString# voranstellen ws1 := WString#'Hallo Welt'; ws2 := WString#'Mehrsprachig';
Sonderzeichen – Fluchtsymbol $
| Escape | Hex | Bedeutung | Beispiel |
|---|---|---|---|
$L / $l | 0x0A | Zeilenvorschub (LF) | '$LText' |
$N | 0x0A+0x0D | Zeilenumbruch LF+CR – 2 Zeichen | '$NText' |
$P / $p | 0x0C | Seitenvorschub (FF) | '$PText' |
$R / $r | 0x0D | Wagenrücklauf (CR) | '$RText' |
$T / $t | 0x09 | Tabulator | '$TText' |
$$ | 0x24 | Dollarzeichen | '100$$' |
$27 | 0x27 | Einfaches Anführungszeichen | '$27Text$27' |
$XX | 0xXX | Beliebiger Hex-Code | '$E4' = ä |
// Steuerzeichen s1 := 'Zeile1$NZeile2'; // Zeilenumbruch LF+CR s1 := 'Spalte1$TSpalte2'; // Tabulator s1 := '$27Text$27'; // einfache Anfuehrungszeichen s1 := 'Preis: 100$$'; // Dollarzeichen // Umlaute im String sicher via Hex-Escape (kein Warning) s1 := '$E4$F6$FC'; // WString: Umlaute direkt moeglich, kein Warning ws1 := WString#'äöü'; ws1 := WString#'Preis: 100$$';
Stringoperationen
// Laenge laenge := LEN(s1); // Verkettung String s1 := CONCAT(IN1 := 'Hallo', IN2 := ' Welt'); s1 := CONCAT_STRING(IN1 := 'Hallo', IN2 := ' Welt'); // Verkettung WString ws1 := CONCAT(IN1 := WString#'Hallo', IN2 := WString#' Welt'); ws1 := CONCAT_WSTRING(IN1 := WString#'Hallo', IN2 := WString#' Welt'); // Teilstring: 5 Zeichen ab Position 1 s2 := MID(IN := s1, L := 5, P := 1); // Einzelzeichen lesen zeichen := s1[1];
Speicherbedarf
// String[20]: 2 Byte Header + 20 Byte Daten = 22 Bytes (immer fest)
// WString[20]: 4 Byte Header + 20x2 Byte = 44 Bytes (immer fest)
// Faustregel: WString belegt doppelt so viel wie String!
Typkonvertierung
ws1 := String_TO_WString(s1); // String nach WString s1 := WString_TO_String(ws1); // WString nach String (Verlust bei Code > 0xFF!) ws1 := WString#'Direktzuweisung'; // korrekt // ws1 := 'Direktzuweisung'; // falsch: wird als String interpretiert!
WString_TO_String() gehen alle Zeichen verloren, deren Unicode-Wert grösser als 0xFF ist (z.B. «€», chinesische Zeichen).Lernkontrolle – Quiz
Beantworte alle Fragen und klicke auf «Auswerten».
1. Wie viele Bytes belegt ein einzelnes Zeichen in einem String?
2. Wie wird eine WString-Konstante in SCL korrekt geschrieben?
3. Wie gross ist der reservierte Speicher eines String[20], wenn nur 3 Zeichen gespeichert sind?
4. Du schreibst s1 := 'Grüezi'; (s1 ist String). Was passiert beim Übersetzen?
5. Wie gibt man «ä» (0xE4) im String-Literal ohne Warnung an?
6. Das Eurozeichen «€» (U+20AC) kann in einem SCL String gespeichert werden.
7. Welche SCL-Escape-Sequenz erzeugt einen Tabulator?