Startseite  Index  <<  >>  

11 - Zeichenkettenverarbeitung

11.1 Einführung

So gut wie kein Computerprogramm kommt ohne Zeichenkettenverarbeitung aus. Fast immer müssen Textinformationen für die Ausgabe aufbereitet oder als Eingabe entgegengenommen werden. Das .NET Framework und damit auch die Programmiersprache C# stellen für diese Zwecke unter anderem die Klassen String und StringBuilder zur Verfügung. Objekte der beiden Klassen können Zeichenketten aufnehmen und stellen eine Vielzahl von Methoden zur Verfügung, mit denen es möglich ist, die Zeichenketten auf die unterschiedlichste Art und Weise zu bearbeiten.

11.2 Die Klasse String

Instanzen dieser Klasse, die sowohl über das Schlüsselwort string als auch durch Verwendung des Klassennamen String erzeugt werden können, enthalten konstante Zeichenketten. Das Schlüsselwort string dient hier nur als Alias für die Klasse. Bei allen Operationen mit einer Zeichenkette vom Typ String wird eine Kopie des Objekts zurückgegeben, welche die vorgenommenen Änderungen enthält. Das originale Objekt wird danach nicht mehr benötigt und im Hintergrund vom GC entsorgt. Aus diesem Grund wird bei Strings von unveränderlichen Objekten gesprochen, da sie nicht direkt manipuliert werden können (z.B. einzelne Zeichen ersetzen).

11.2.1 Strings initialisieren

Die folgende Aufzählung stellt mehrere Möglichkeiten vor, eine Zeichenkette zu initialisieren. Zeichenketten stellen im .NET Framework eine Besonderheit dar, da sie sowohl direkt durch eine Wertzuweisung als auch über einen Konstruktor initialisiert werden können.

  • Grundsätzlich kann einer Variablen vom Typ String jede in Anführungszeichen stehende Zeichenkette übergeben werden. "Grundsätzlich" deshalb, da Sie bei der Verwendung von Sonderzeichen einige Konventionen beachten müssen (vgl. Abschnitt "Formatierung mit Escapesequenzen").
  • Eine leere Zeichenkette lässt sich durch Zuweisung zweier aufeinander folgender Anführungszeichen oder durch Zuweisung der Eigenschaft String.Empty erzeugen.
  • Verwenden Sie einen der Konstruktoren der Klasse String, die vielfältigere Initialisierungen zulassen.

    Beispiel: Zeichenketten initialisieren

    string str1 = "CSharpBuch";        // Zeichenkette zuweisen
    string str2 = "";                  // Leerstring zuweisen
    string str3 = String.Empty;        // Leerstring zuweisen
    string str4 = new String(' ', 10); // String mit 10 Leerzeichen

    INFO

    Prinzipiell lassen sich string und String beide äquivalent einsetzen. Im Buch wird string in der Regel bei der Definition des entsprechenden Datentyps und String beim Zugriff auf die Methoden der Klasse String verwendet.

    Leere und nicht zugewiesene Zeichenketten

    Durch die Zuweisung von null an einen String wird nicht automatisch eine leere Zeichenkette erzeugt. Eine nachfolgende Prüfung mit String.Empty liefert nicht den Wert true, da die Zeichenkette nicht initialisiert ist. Beim Zusammensetzen von Zeichenketten verhält sich eine solche Zeichenkette dann allerdings wie eine leere Zeichenkette, d.h., die Verwendung von null bei der Verkettung führt nicht zu einem Fehler. Wenn Sie mit einer Abfrage prüfen wollen, ob eine Zeichenkette einen Inhalt hat, können Sie die statische Methode IsNullOrEmpty() der Klasse String verwenden, der Sie als Parameter die zu prüfende Zeichenkette übergeben. Sie liefert true, wenn der String leer oder null ist. Die Prüfung auf null erfolgt direkt über den Vergleichsoperator.

    Beispiel: Leere und nicht initialisierte Strings prüfen

    using System;
    namespace CSharpBuch.Kap11
    {
      public class ZeichenkettenOperationen
      {
        static void Main(string[] args)
        {
          string str = null;
          if(str == null)
            Console.WriteLine("str ist null: " + str);
          if(str == String.Empty)
            Console.WriteLine("str ist leer: " + str);
          if(String.IsNullOrEmpty(str))
            Console.WriteLine("str ist leer oder null: " + str);
          Console.ReadLine();
        }
      }
    }
    Listing 11.1: ZeichenkettenOperationen.cs

    11.2.2 Länge einer Zeichenkette ermitteln

    Oft ist es notwendig, zu ermitteln, aus wie vielen Zeichen eine Zeichenkette besteht, z.B. um sie zeichenweise zu durchlaufen. Zu diesem Zweck verwenden Sie die Eigenschaft Length der Klasse String.

    Beispiel: Längenbestimmung einer Zeichenkette

    string str = "CSharpBuch"; Console.WriteLine(str.Length);

    11.2.3 Zugriff auf einzelne Zeichen

    Die Eigenschaft Length gibt die Anzahl der Zeichen vom Typ Char an, die sich in einer Zeichenkette befinden. Da der Typ Char ein Unicode-Zeichen repräsentiert, besteht eine Zeichenkette ebenfalls aus Unicode-Zeichen. Auf die Elemente eines Strings kann wie bei einem Array zugegriffen werden, indem ein Index zwischen 0 und Stringlänge - 1 angegeben wird. Da Strings unveränderliche Objekte sind, kann ein Zeichen aber nicht verändert werden. Es ist sozusagen schreibgeschützt.

    Beispiel: Schreibweisen von Bezeichnern

    Auf die Zeichen einer Zeichenkette kann über einen Index wie bei einem Array zugegriffen werden. Mittels einer for-Schleife lässt sich der gesamte String zeichenweise durchlaufen. Beachten Sie, dass zur Ausgabe eines einzelnen Zeichens die Methode ToString() verwendet wird, da sonst der Zahlencode des Zeichens verwendet und somit die Summe der Zahlencodes der drei Zeichen ausgegeben würde.

    string str = "CSharpBuch";
    Console.WriteLine(str[0].ToString() + str[3].ToString() +
                      str[4].ToString()); // liefert "Car"
    // oder
    for(int i = 0; i < str.Length; i++)
      Console.Write(str[i].ToString());   // gibt "CSharpBuch" aus

    Sie können auch mithilfe der Methode GetEnumerator() der String-Klasse alle Zeichen einer Zeichenkette einzeln durchlaufen. Allerdings haben Sie dann keinen Index zur Verfügung.
    string str = "CSharpBuch"; 
    CharEnumerator en = str.GetEnumerator();
    while(en.MoveNext())
      Console.WriteLine(en.Current.ToString());

    11.2.4 Weitere Operationen mit Zeichenketten

    Die folgenden Abschnitte behandeln verschiedene Vorgehensweisen, die bei der Arbeit mit Zeichenketten auftreten können.

    Verketten von Zeichenketten mit dem +- Operator

    Das Zusammensetzen von Zeichenketten ist eine der häufigsten Operationen überhaupt. Deshalb gibt es dafür auch verschiedene Möglichkeiten. Die am meisten praktizierte Form des Zusammensetzens von Zeichenketten verwendet einfach das von der Addition bekannte Pluszeichen.

    Beispiel: Durchführen der Zeichenverkettung

    Es lassen sich mit dem Pluszeichen nicht nur Strings, sondern beliebige Objekte miteinander verknüpfen. Allerdings muss sich mindestens ein String-Objekt darunter befinden. Alle anderen Werte werden dann implizit nach String konvertiert. Ansonsten bemängelt der Compiler eine fehlerhafte Zuweisung, z.B. von int nach String. Für ein Objekt oder eine Zahl wird in diesem Fall dessen Methode ToString() aufgerufen, bevor es mit dem Rest verkettet wird.

    Verwenden Sie in einer Methode wie WriteLine() bei der Verkettung beispielsweise nur Integer-Zahlen, wird zuerst deren Summe gebildet und diese dann als int-Parameter an die Methode übergeben. Also auch hier ist Vorsicht geboten.

    int zahl1 = 10;
    int zahl2 = 11;
    string s = zahl1 + "";                  // gibt "10" aus
    string s = zahl1 + zahl2;               // Compilerfehler
    Console.WriteLine("" + zahl1 + zahl2);  // gibt 1011 aus
    Console.WriteLine(zahl1 + zahl2);       // gibt 21 aus

    Beispiel: Verschiedene Varianten, Strings zu verketten

    Im folgenden Programm wird eine große Zeichenkette mithilfe einer Schleife von 20.000 Durchläufen aus Teilzeichenketten zusammengesetzt. Die Teilzeichenketten bestehen jeweils aus dem String Hallo sowie dem Wert der Schleifenvariablen i, so dass sich eine Zeichenkette der Form Hallo0Hallo1Hallo2... ergibt. Das Programm bietet alle drei möglichen Methoden zum Verketten von Zeichenketten zur Auswahl an, wobei die zu füllende Zeichenkette den einzelnen Methoden als Referenz übergeben wird. Hier wird zunächst die erste Methode VerkettePlus() vorgestellt.

    Außerdem enthält die Anwendung einige Methoden zur Zeitmessung und zum Verarbeiten von Zeichenketten, die hier ohne weitere Erläuterung verwendet werden. Beim Testen der Anwendung werden Sie feststellen, dass die einfache Stringverkettung sowie die Verwendung der Methode Concat() am langsamsten sind.

    using System;
    using System.Text;
    namespace CSharpBuch.Kap11
    {
      public class ZeichenkettenVerbinden
      {
        const int iterationen = 20000; 
        static string str = String.Empty;
        static void VerkettePlus(ref string str)
        {
          for(int i = 0; i < iterationen; i++)
            str += "Hallo + i.ToString();
        }
        ...
        static void Main(string[] args)
        {
          Console.WriteLine("Wählen Sie aus: \n" 
            + "1 - Verkettung mit '+'\n" 
            + "2 - Verkettung mit Concat()\n" 
            + "3 - Verkettung mit StringBuilder\n" 
            + "4 - Ende\n\n");
          ConsoleKeyInfo cki = Console.ReadKey(true); 
          DateTime startZeit = DateTime.Now; 
          switch(cki.Key)
          {
            case ConsoleKey.D1: VerkettePlus(ref str);
                                break;
            case ConsoleKey.D2: VerketteConcat(ref str);
                                break;
            case ConsoleKey.D3: VerketteStringBuilder(ref str);
                                break;
            case ConsoleKey.D4: return;
          }
          DateTime endZeit = DateTime.Now;
          TimeSpan differenz = endZeit.Subtract(startZeit); 
          Console.WriteLine("Schleifendurchläufe   : " + 
                            iterationen.ToString());
          Console.WriteLine("Länge der Zeichenkette: " +
                            str.Length.ToString());
          Console.WriteLine("Benötigte Zeit (s)    : " +
                            differenz.TotalSeconds.ToString());
          Console.ReadKey();
        }
      }
    }
    Listing 11.2: ZeichenkettenVerbinden.cs

    Zusammensetzen mit der Methode Concat()

    Der Vorteil der Methode Concat() der Klasse String ist, dass mehrere Strings, die in Forms eines Arrays vorliegen, mit einem einzigen Befehl verknüpft werden können. Concat() akzeptiert eine beliebig lange Liste von Parametern und als Parameter jedes beliebige Objekt.

    Beispiel: Zeichenketten über Concat() verknüpfen

    Das zuletzt verwendete Beispiel enthält auch eine Methode, die durch den Einsatz von Concat() die gleiche Aufgabe löst. Die mittels Concat() gebildeten Teilzeichenketten werden in jedem Schleifendurchlauf in der per Referenz übergebenen Variablen str abgelegt. Diese wird dann wiederum der Methode Concat() übergeben.
    static void VerketteConcat(ref string str)
    {
      for(int i = 0; i < iterationen; i++)
        str = String.Concat(str, "Hallo", i.ToString());
    }
    Listing 11.3: ZeichenkettenVerbinden.cs

    INFO

    Wenn Sie mehrere Strings zusammensetzen wollen, die sich in einem Array befinden, und diese zusätzlich mit einem bestimmten Zeichen trennen möchten, verwenden Sie die Methode String.Join(), z.B.
    string[] felder = {"Name", "Vorname", "Plz"};
    string zeile = String.Join(";", felder);
    // liefert Name;Vorname;Plz

    TIPP

    Nach dem Muster der bisherigen Beispiele würde die Verkettung großer Zeichenketten ziemlich lange dauern. Solche Datenmengen werden z.B. schnell erreicht, wenn Log-Informationen (Informationen über den internen Zustand einer Anwendung) gesammelt werden, die vielleicht später in eine Datei ausgegeben werden sollen. Das Problem liegt darin, dass die Zeichenketten immer länger werden und der Garbage Collector immer mehr Speicher beanspruchen und wieder freigeben muss - und dies bei jeder Zuweisung einer Zeichenkette an ein String-Objekt. Verwenden Sie deshalb zum Verketten großer bzw. vieler Zeichenketten nach Möglichkeit nicht die Klasse String, sondern die später in diesem Kapitel beschriebene Klasse StringBuilder.

    Zeichenketten aufteilen

    Wenn verschiedene Informationen zu einer Zeichenkette zusammengesetzt werden, entsteht bei der darauf folgenden Datenverarbeitung oft die Notwendigkeit, diese Zeichenketten wieder in ihre einzelnen Bestandteile zu zerlegen. Dabei kommt die Methode Split() zum Einsatz. Diese Methode übernimmt als Parameter ein Array vom Typ Char, das ein oder mehrere Trennzeichen enthält. Der betreffenden String wird dann an den Stellen, an denen eines dieser Trennzeichen gefunden wird, geteilt und in ein Array eingefügt.

    Beispiel: Zeichenketten mit Trennzeichen in ihre Bestandteile zerlegen

    Im folgenden Programm wird eine Zeichenkette in einzelne Teile zerlegt, wobei ein Semikolon und ein Leerzeichen als Trennzeichen verwendet werden. Das erhaltene Array wird dann über foreach durchlaufen und sein Inhalt ausgegeben.

    using System;
    namespace CSharpBuch.Kap11
    {
      public class ZeichenkettenTeilen
      {
        static void Main(string[] args)
        {
          string zeile = "Dies;ist ein Test;String";
          char[] c = new char[] { ';', ' ' }; 
          string[] spalten = zeile.Split(c);
          foreach(string str in spalten)
            Console.WriteLine(str);
          Console.ReadLine();
        }
      }
    }
    Listing 11.4: ZeichenkettenTeilen.cs

    INFO

    Zeichenketten mit Trennzeichen werden häufig zum Datenaustausch verwendet, da dieses Format von jedem Programm verarbeitet und erstellt werden kann. Jede Zeile enthält dazu die Elemente eines Datensatzes (einer Informationseinheit wie Name;Vorname;Ort;....) wobei jedes Element vom nächsten durch ein Trennzeichen abgeteilt wird. Zur Unterscheidung von Zahlen und Text wird Text meist noch in Anführungszeichen eingeschlossen.

    Zeichenketten kopieren

    Um die Kopie einer Zeichenkette zu erstellen, weisen Sie den Rückgabewert der Methode String.Copy() einer Variablen vom Typ String zu. Die Verwendung der Methode Clone() führt dagegen nicht zu einem zweiten Objekt, das mit dem ersten identisch ist, sondern liefert nur einen Verweis auf das ursprüngliche Objekt zurück.

    Beispiel: Kopien von Zeichenketten erstellen

    string str1 = "Hallo!";
    string str2 = str1.Clone().ToString();  // nur Verweis
    string str3 = String.Copy(str1);  // echte Kopie
    Console.WriteLine(str2 + " " + str3);

    TIPP

    Wenn Sie nur Teile einer Zeichenkette kopieren wollen, verwenden Sie am besten die Methode CopyTo() der Klasse String. Dabei müssen Sie ein Array vom Typ Char als Parameter übergeben, in das die gewünschten Zeichen kopiert werden. Den Startindex sowie die Anzahl der zu kopierenden Zeichen können Sie ebenfalls als Parameter übergeben.

    Teilzeichenketten mit der Methode Substring() ermitteln

    Die Methode Substring() gibt eine Teilzeichenfolge einer Zeichenkette zurück. Dabei gibt der erste Parameter den Startindex und der optionale zweite Parameter die Länge der Teilzeichenkette an. Wenn dieser Parameter fehlt, wird die restliche Zeichenkette zurückgeliefert.

    Beispiel: Teile von Zeichenketten auslesen

    string str1 = "Hallo Welt!";
    string str2 = str1.Substring(6, 4); // liefert "Welt"
    Console.WriteLine(str2);

    Suchen mit den Methoden IndexOf() bzw. IndexOfAny()

    Diese beiden Methoden geben den Index bzw. die Position (mit 0 beginnend) eines Zeichens oder einer Teilzeichenkette innerhalb einer Zeichenkette zurück. Optional kann als zweiter Parameter eine Startposition und als dritter Parameter eine Länge (Anzahl der Zeichen) für die Suche angegeben werden. Der Methode IndexOfAny() wird an Stelle eines einzelnen Zeichens ein Char-Array übergeben, das ein oder mehrere Zeichen enthält, nach denen gesucht werden soll.

    Beispiel: Suche nach dem ersten Vorkommen eines Zeichens oder einer Teilzeichenkette

    string str1 = "Hallo Welt!";
    int x = str1.IndexOf('t');               // ergibt 9
    x = str1.IndexOf("ll");                 // ergibt 2
    x = str1.IndexOfAny(new Char[] {'l'});  // ergibt 2

    INFO

    Wenn Sie nicht das erste, sondern das letzte Vorkommen eines Zeichens oder einer Teilzeichenkette innerhalb einer Zeichenkette ermitteln wollen, verwenden Sie analog die Methoden LastIndexOf() bzw. LastIndexOfAny().

    Suchen mit den Methoden StartsWith() bzw. EndsWith()

    Mit StartsWith() und EndsWith() können Sie nach Zeichenketten suchen, die mit einem bestimmten Zeichen oder mit einer bestimmten Zeichenfolge beginnen oder enden.

    Beispiel: Suche am Beginn oder Ende einer Zeichenkette

    string str1 = "Hallo Welt!";
    if(str1.StartsWith("Hallo"))
      ...
    if(str1.EndsWith("!"))
      ...

    Zeichenketten vergleichen

    Die einfachste Möglichkeit, zwei Zeichenketten miteinander zu vergleichen, bieten die beiden Vergleichsoperatoren == und !=. Dabei wird immer die Groß- und Kleinschreibung berücksichtigt.

    Beispiel: Zeichenketten vergleichen

    string str1 = "Hallo!";
    string str2 = "Hallo!";
    if(str1 == str2)
      ...
    if(str1 != str2)
      ...

    Die gleiche Funktion erfüllt auch die Methode Equals(), bei der allerdings weitergehende Einstellungen bezüglich der Art und Weise des Vergleichs (z.B. länderspezifische Besonderheiten, Groß- und Kleinschreibung) berücksichtigt werden können.

    if(str1.Equals(str2, StringComparison.CurrentCulture))
      ...

    Als weitere Alternative zum Vergleichen von Zeichenketten stehen die Instanzmethode CompareTo() und die statische Methode String.Compare() zur Verfügung. Die Methode String.Compare() ermöglicht wie die Methode Equals() z.B. die Berücksichtigung länderspezifischer Besonderheiten. Im Unterschied zur Methode Equals() geben die Methoden CompareTo() und String.Compare() keinen booleschen Wert zurück, sondern

  • 0, wenn beide Strings gleich sind,
  • 1, wenn der erste String lexikalisch größer ist,
  • -1, wenn der zweite größer ist.

    Verwendet werden dabei die den Zeichen einer Zeichenkette zugeordneten Codewerte. Wenn die absolute Differenz dieser Werte ermittelt werden soll, steht dafür die Methode CompareOrdinal() zur Verfügung.

    Beispiel: Zeichenketten lexikalisch vergleichen

    string str1 = "Hallo!";
    string str2 = "Welt!";
    Console.WriteLine(str1.CompareTo(str2).ToString());                                           // -1
    Console.WriteLine(String.Compare(str1, str2, StringComparison.CurrentCulture).ToString());    // -1
    Console.WriteLine(String.CompareOrdinal(str1, str2).ToString());                              // -15

    Zeichenketten beschneiden

    Es kommt vor, dass Zeichenketten am Anfang und/oder am Ende Zeichen enthalten, die überflüssig bzw. unerwünscht sind. In der Regel sind dies Leerzeichen oder Tabulatoren. Die Methode Trim() entfernt diese Zeichen, und zwar sowohl am Anfang als auch am Ende der Zeichenkette. Dabei kann der Methode ein Array vom Typ Char übergeben werden, dass die zu entfernenden Zeichen enthält. Ohne diese Angabe werden nur so genannte Whitespace-Zeichen (Leerzeichen, Tabulatoren, Zeilenumbrüche) entfernt.

    string str1 = "  ;Hallo!;   ";
    Console.WriteLine(str1.Trim(new char[]{ ' ', ';' }));  // "Hallo!" 

    INFO

    Beschränkt sich das Entfernen von Zeichen nur auf den Anfang oder das Ende einer Zeichenkette, verwenden Sie die Methoden TrimStart() bzw. TrimEnd().

    Zeichenketten ausrichten

    Für die Ausgabe von Daten kann es erforderlich sein, Zeichenketten unterschiedlichen Inhalts eine feste Länge zuzuweisen. Dies ist mithilfe der Methoden PadLeft() und PadRight() möglich. Die gewünschte Länge der Zeichenkette wird über den ersten Parameter angegeben. Mit dem zweiten Parameter lässt sich definieren, welches Zeichen zum Auffüllen der überflüssigen Zeichen verwendet werden soll.
    string str = "Hallo Welt!";
    char pad = Convert.ToChar(".");
    Console.WriteLine(str.PadRight(15, pad));  // "Hallo Welt!...."
    Console.WriteLine(str.PadLeft(15, pad));   // "....Hallo Welt!"

    Zeichen und Zeichenketten löschen

    Wenn Sie eine Zeichenkette nicht mehr benötigen, wird sie automatisch vom Garbage Collector entsorgt. Um dies zu beschleunigen, können Sie der entsprechenden Variablen auch den Wert null zuweisen. Falls Sie die Variable weiterverwenden wollen, weisen Sie ihr String.Empty zu, um den Inhalt der Zeichenkette zu löschen. Es gibt aber auch Fälle, in denen nur Teile einer Zeichenkette entfernt werden sollen. Für diesen Zweck eignet sich die Methode Remove() der String-Klasse. Ihr übergeben Sie den Startindex und im zweiten Parameter die Anzahl der Zeichen, die entfernt werden sollen.

    string str = "Hallo Welt!";
    Console.WriteLine(str.Remove(5, 5));   // Es bleibt "Hallo!" übrig

    Zeichenketten einfügen

    Um ein Zeichen oder eine Zeichenkette in eine andere Zeichenkette einzufügen, verwenden Sie die Methode Insert() der String-Klasse. Als Parameter sind die Einfügeposition sowie die einzufügende Zeichenkette zu übergeben. Der Rückgabewert enthält den resultierenden String.

    string str = "Hallo Welt!";
    Console.WriteLine(str.Insert(6, "meine ")); //"Hallo meine Welt!"

    Zeichenketten ersetzen

    Mit der Methode Replace() der String-Klasse können Sie einzelne Zeichen oder ganze Zeichenfolgen innerhalb einer Zeichenkette ersetzen. Als Parameter müssen jeweils das alte und das neue Zeichen bzw. die alte und die neue Zeichenfolge übergeben werden. Der Rückgabewert enthält den resultierenden String.

    string str = "Hallo Welt!";
    Console.WriteLine(str.Replace("Hallo", "Neue")); // "Neue Welt!"

    Zeichenketten konvertieren

    Um eine Zeichenkette oder Teile davon in ein Char-Array von Unicode-Zeichen zu konvertieren, verwenden Sie die Methode ToCharArray() der Klasse String. Wenn nur ein Teil der Zeichenkette konvertiert werden soll, ist als erster Parameter die Startposition und als zweiter Parameter die Länge der Teilzeichenkette anzugeben.

    string str = "Hallo Welt!";
    char[] arr = str.ToCharArray();
    Console.WriteLine(arr[6].ToString());   // "W"
    Es ist auch möglich, Zeichenketten von Großbuchstaben zu Kleinbuchstaben zu konvertieren und umgekehrt. Dazu dienen die Methoden ToUpper() für die Großschreibung und ToLower() für die Kleinschreibung. Optional kann als Parameter eine Instanz der CultureInfo-Klasse übergeben werden, so dass länderspezifische Besonderheiten berücksichtigt werden können.

    string str = "Hallo Welt!";
    Console.WriteLine(str.ToUpper());   // "HALLO WELT!"
    Console.WriteLine(str.ToLower());   // "hallo welt!"

    INFO

    Wenn Sie Benutzereingaben über String-Vergleiche prüfen, sollten Sie immer darauf achten, ob diese Werte die Groß- und Kleinschreibung beachten oder nicht. Falls nicht, wandeln Sie während des Vergleichs den eingegebenen Wert in Groß- oder Kleinbuchstaben um.

    string eingabe = BenutzereingabeErmitteln();
    if(eingabe.ToLower() == "exit")
      ... // Anwendung beenden

    11.2.5 Zeichenketten formatieren

    Um Daten in besonderer Weise zu formatieren, verwenden Sie die Methode Format() der Klasse String. So lassen sich Zahlen mit Tausendertrennzeichen oder Datumsangaben mit unterschiedlichen Formaten ausgeben. Der Methode Format() wird als erster Parameter ein so genannter Formatstring übergeben, der die Formatierung steuert. Als zweiter Parameter kann ein Array von Werten übergeben werden, deren Werte dann in die Platzhalter des Formatstrings eingesetzt werden.

    Formatierungszeichen

    Die folgende Tabelle zeigt eine Auswahl von Formatierungszeichen. Platzhalterzeichen wie das Tausender- oder Dezimaltrennzeichen werden abhängig von den Ländereinstellungen ersetzt.

    FormatzeichenBeschreibung
    0Platzhalter für Ziffern. An dieser Stelle wird eine Ziffer oder eine Null angezeigt.
    #Platzhalter für Ziffern. Hier wird eine Ziffer oder nichts angezeigt.
    .Platzhalter für Dezimaltrennzeichen
    ,Platzhalter für Tausendertrennzeichen
    %Platzhalter für das Prozentzeichen
    + oder -Vorzeichen (Plus oder Minus)
    C bzw. cDieses Währungsformat erzeugt ein Zahlenformat mit Tausendertrennzeichen. Es werden zwei Dezimalstellen angezeigt. Das verwendete Währungssymbol hängt von Ihren Einstellungen ab.
    D bzw. d Dezimale Ausgabe
    E bzw. eWissenschaftliche Ausgabe von Gleitkommazahlen
    F bzw. fDarstellung mit festem Komma von Gleitkommazahlen
    G bzw. gAllgemeine Ausgabe von Gleitkommazahlen
    N bzw. nZiffernausgabe mit Tausendertrennzeichen
    P bzw. pAusgabe in Prozent mit zwei Dezimalstellen
    X bzw. xHexadezimale Ausgabe
    HH:mm:ss
    hh:mm:ss
    Zeigt die Stunden, Minuten und Sekunden als Zahlen mit führender 0 an. Die Stunden werden im 24-Stunden-Format angezeigt, bei Verwendung von hh statt HH im 12-Stunden-Format.
    dddd / ddZeigt den Tag ausgeschrieben bzw. als Zahl mit führender Null an.
    MMMM / MMZeigt den Monat ausgeschrieben bzw. als Zahl mit führender Null an.
    yyyy / yyZeigt das Jahr vierstellig bzw. zweistellig mit führender Null an.
    FEs wird das lange Datumsformat und das lange Zeitformat des ausgewählten Gebietsschemas benutzt.
    gDas kurze Datumsformat und das 24-Stunden-Zeitformat werden verwendet.
    dZeigt einen Datumswert entsprechend dem kurzen Datumsformat des ausgewählten Gebietsschemas an.
    DZeigt einen Datumswert entsprechend dem langen Datumsformat des ausgewählten Gebietsschemas an.
    tVerwendet für eine Anzeige von Stunden und Minuten das 24-Stunden-Format.
    TZeigt Stunden, Minuten und Sekunden entsprechend dem langen Zeitformat des ausgewählten Gebietsschemas an.
    Tabelle 11.1: Übersicht der Formatierungszeichen

    Beispiel: Einsatz verschiedener Formatierungen

    Im folgenden Programm werden verschiedene Zeichenkettenformatierungen eingesetzt, die auf Zahlen- und Datumsangaben angewendet werden.

    using System;
    namespace CSharpBuch.Kap11
    {
      public class ZeichenkettenFormatierung
      {
        static void Main(string[] args)
        {
          Console.WriteLine("{0:d}", DateTime.Now);
          Console.WriteLine("{0:t}", DateTime.Now);
          Console.WriteLine(DateTime.Now.ToString("h:mm:ss.fff"));
          String str1 = DateTime.Now.ToString("f");
          String str2 = DateTime.Now.ToString("HH.mm");
          String str3 = String.Format("{0:HH:mm:ss}", DateTime.Now);
          String str4 = String.Format("{0:dddd MMMM}", DateTime.Now);
          String str5 = String.Format("{0:C}", 153.45643);
          String str6 = String.Format("{0:###0.00}", 274.965);
          String str7 = String.Format("Von {0} bis {1}", 2, 99);
          String str8 = String.Format("{0:0.00%} {1:0.00}",3.44,6.443);
          Console.WriteLine("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}",
                            str1, str2, str3, str4, str5, str6, str7, str8);
          Console.ReadKey();
        }
      }
    }
    Listing 11.5: ZeichenkettenFormatierung.cs Ausgabe:
    20.05.2008
    10:20
    10:20:41.406
    Dienstag, 20. Mai 2008 10:20
    10.20
    10:20:41
    Dienstag Mai
    153,46 ?    <= Das Eurozeichen kann nicht dargestellt werden
    274,97
    Von 2 bis 99
    344,00% 6,44

    INFO

    Bei benutzerdefinierten Zahlenformatierungen kann der Formatierungsstring bis zu drei Bereiche enthalten, um für die Zahlenbereiche >0, <0 und 0 unterschiedliche Formatierungen darstellen zu können. Diese Bereiche werden durch Semikolons getrennt. Sind es nur zwei Bereiche, repräsentiert der erste Bereich positive Zahlen und Null und der zweite Bereich negative Zahlen. Wenn es dagegen drei Bereiche sind, steht der erste Bereich für positive, der zweite für negative Zahlen und der dritte für Nullwerte.

    Formatierung mit Escapesequenzen

    Die Ausgabe von Zeichen und Zeichenketten lässt sich zusätzlich mithilfe spezieller Escapesequenzen steuern, die direkt im String eingefügt und mit einem Backslash eingeleitet werden. Aus diesem Grund können Sie einem String nicht jede beliebige Zeichenkette zuweisen, da die Steuerzeichen korrekt angegeben werden müssen. Mit Escapesequenzen lassen sich z.B. Zeilenumbrüche oder Tabulatoren in den Text einfügen.
    EscapesequenzBedeutung Beispiel
    \'Apostroph ausgebenConsole.WriteLine("Der Apostroph in dog\'s ...");
    \"Anführungszeichen ausgebenConsole.WriteLine("\"Der Text wird in Anführungszeichen eingeschlossen.\"");
    \\Backslash ausgeben Console.WriteLine("C:\\Windows\\Desktop");
    \0null (nicht null)- z.B. zur Markierung des Endes einer ZeichenketteString str = "\0";
    Console.WriteLine(str);
    \bRückschrittConsole.WriteLine("Ha\bllo");
    \nZeilenwechsel (Linefeed)Console.WriteLine("Ha\nllo");
    \rWagenrücklauf (Carriage Return)Console.WriteLine("Ha\rllo");
    \tHorizontaler TabulatorConsole.WriteLine("Ha\tllo");
    Tabelle 11.2: Escapesequenzen und ihre Bedeutung

    Verbatim-Strings

    In C# können Sie Zeichenketten durch Voranstellen des Zeichens @ deklarieren, so dass alle enthaltenen Zeichen (auch Steuerzeichen) als Teile der Zeichenkette interpretiert werden. Dabei ist zu beachten, dass Anführungszeichen innerhalb eines solchen Strings immer doppelt anzugeben sind. Verbatim-Strings kommen oft bei Verzeichnisangaben zum Einsatz, da in "normalen" Strings der Backslash sonst doppelt angegeben werden muss.

    string path = "C:\\Windows\\Temp";
    string path = @"C:\Windows\Temp";
    string str  = @"Ein so genannter ""Verbatim-String"".";

    11.3 Die Klasse StringBuilder

    11.3.1 Anwendungsgebiet

    Im Unterschied zur Klasse String verwaltet ein Objekt der Klasse StringBuilder aus dem Namespace System.Text Zeichenketten variabler Länge. Der Speicherbedarf bei Veränderungen wird in diesem Fall dynamisch angepasst. Das bedeutet, dass bei zeitkritischen Operationen mit vielen oder langen Zeichenketten ein Vorteil gegenüber der String-Klasse entsteht, weil die Speicherreservierung wesentlich schneller vonstatten geht und das Kopieren der Objekte nicht nötig ist. Allerdings stehen nicht so viele Zeichenketten-Operationen zur Verfügung wie in der Klasse String. Wird im Konstruktor keine Kapazität angegeben, wird zunächst ein 16 Byte großer Puffer erzeugt, der bei Bedarf immer wieder verdoppelt wird. Wie bei Strings hat er eine maximale Kapazität wie der Wert Int32.MaxValue angibt. Durch eine geschickte Wahl können Sie die Kapazität selbst festlegen und so unnötige Verdopplungen und die damit verbundenen Kopiervorgänge unterbinden.

    Der Zugriff auf die in einem StringBuilder-Objekt gespeicherte Zeichenkette erfolgt über die Methode ToString(). Eine Eigenschaft wie Text oder der Zugriff auf einzelne Zeilen ist nicht möglich.

    TIPP

    Verwenden Sie nach Möglichkeit die Klasse StringBuilder, wenn Sie mit sehr großen oder mit sehr vielen Zeichenketten arbeiten.

    11.3.2 Verketten mit Append()

    Bei der Arbeit mit der Klasse StringBuilder muss zunächst immer ein Objekt dieser Klasse erstellt werden. Dem Konstruktor kann dabei die Ausgangszeichenkette übergeben werden. Wenn dies nicht erfolgt, wird die Instanz standardmäßig mit dem Wert String.Empty initialisiert. Anschließend ist es dann möglich, die Zeichenkette durch Aufrufen der Methode Append() um beliebig viele weitere Zeichen und Zeichenketten zu erweitern.

    Beispiel: Zeichenketten effektiv und schnell verketten

    Das bereits beim Zusammensetzen von Zeichenketten mit Methoden der Klasse String verwendete Beispiel enthält noch die Methode VerketteStringBuilder(), die durch den Einsatz eines Objekts der Klasse StringBuilder die gestellte Aufgabe löst. Durch die eingebaute Zeitmessung können Sie sehen, dass diese Methode beim Verknüpfen vieler Zeichenketten die schnellste mit einer 500- bis 1000-fach schnelleren Verarbeitung ist.

    // Zusammensetzen mit StringBuilder
    static void VerketteStringBuilder(ref string str)
    {
      StringBuilder sb = new StringBuilder();
      for(int i = 0; i < iterationen; i++)
        sb.Append("Hallo" + i.ToString());
      str = sb.ToString();
    }
    Listing 11.6: ZeichenkettenVerbinden.cs

    11.3.3 Einfügen, Ersetzen oder Entfernen

    Wie bei String-Objekten können Sie auch bei einem StringBuilder-Objekt Zeichen oder Zeichenketten einfügen, ersetzen oder entfernen. Verwenden Sie dazu die Methoden Insert(), Replace() und Remove().

    Beispiel: Daten in einem StringBuilder-Objekt bearbeiten

    StringBuilder sb = new StringBuilder("Hallo Welt!");
    sb.Insert(5, ", meine ");
    Console.WriteLine(sb.ToString());      // "Hallo, meine Welt!"
    sb.Replace("meine", "kleine");
    Console.WriteLine(sb.ToString());      // "Hallo, kleine Welt!"
    sb.Remove(5, 8);
    Console.WriteLine(sb.ToString());      // "Hallo Welt!"

    11.4 Übungsaufgaben

    Aufgabe 1

    Erstellen Sie ein Projekt, in dem Sie das Verknüpfen von Zeichenketten über die Methode Concat() der String-Klasse realisieren. Erstellen Sie einige Zeichenketten, die Bestandteile Ihrer Adresse enthalten. Verknüpfen Sie diese und geben Sie die entstandene Zeichenkette auf der Konsole aus.

    Aufgabe 2

    Erstellen Sie eine Zeichenkette, die am Anfang einige Nullen und am Ende einige Leerzeichen enthält. Schneiden Sie sowohl die Nullen als auch die Leerzeichen anschließend mithilfe der geeigneten Methoden ab.

    Aufgabe 3

    Lesen Sie innerhalb einer Schleife von der Konsole eine Zeichenkette ein und geben Sie diese umgekehrt wieder aus. Fragen Sie anschließend den Anwender, ob er die Anwendung beenden will. Mögliche Eingaben sind Ja und Nein. Konvertieren Sie die Antwort in Großbuchstaben und prüfen Sie den Wert. Damit verhindern Sie, dass die Abfrage versehentlich durch eine falsche Schreibweise nicht richtig beantwortet wurde.

    Aufgabe 4

    Erstellen Sie eine Zeichenkette, die sich aus mehreren Teilzeichenketten zusammensetzt, die alle mit einem Semikolon voneinander getrennt sind. Verwenden Sie anschließend die Methode Split() der Klasse String, um die einzelnen Teile der Zeichenkette wieder voneinander zu trennen. Geben Sie die gewonnenen Teilzeichenketten am Bildschirm aus.

    Aufgabe 5

    Formatieren Sie die Zahl 5 einmal als Prozentangabe, einmal als ganze Zahl, einmal als Dezimalzahl mit zwei Dezimalstellen und einmal als Währung (EUR). Beachten Sie, dass bei der Ausgabe der Währung das Eurozeichen manchmal nur als Fragezeichen dargestellt wird. Das verwendete Währungssymbol kann in den Systemeinstellungen (SYSTEMSTEUERUNG/REGIONS- UND SPRACHOPTIONEN bzw. ZEIT, SPRACHE UND REGION geändert werden).