Zum Inhalt springen
Topos Uranos

Zusammenfassung

Text ist das häufigste Datum eines Programms: Namen, Meldungen, Zeilen einer Datei, Befehle eines Benutzers. Diese Lektion behandelt ihn als das, was er für C++ ist, eine Folge von Zeichen mit eigenen Operationen. Sie stellt std::string vor, das man erzeugt, verkettet, vergleicht und durchläuft wie einen Vektor von char im Dienst des Textes; seine Such- und Extraktionsoperationen (find, substr, starts_with, contains) und den Wert std::string::npos, mit dem find sagt, dass es nichts gefunden hat; std::string_view, die View, die einen Text beobachtet, ohne ihn zu kopieren, und die Bedingung, von der sie abhängt: dass der beobachtete Text weiterhin existiert. Den Abschluss der Lektion bilden die C-Strings, um fremden Code zu lesen, und die Ordnung, in der C++ Wörter vergleicht und sortiert.

Lernziele

  1. Die Operationen von std::string (size, +, find, substr, starts_with, contains) verwenden, um Textprobleme zu lösen.
  2. Das Ergebnis von find deuten und gegen std::string::npos prüfen, und vorhersagen, was geschieht, wenn man es wie eine beliebige Zahl behandelt.
  3. Text in einer Funktion als std::string_view entgegennehmen und an einem Beispiel erklären, warum eine View die Zeichenkette, die sie beobachtet, nicht überleben darf.
  4. Code mit C-Strings lesen und ihre Unterschiede zu std::string erklären: den Nullterminator, die feste Größe und die Summe zweier Literale, die nicht kompiliert.

Die Zeichenkette std::string

Erzeugen, verketten, durchlaufen

Die Lektion Zeichen, boolesche Werte, Umwandlungen und Konstanten hat das Zeichen, char, als eine kleine Zahl vorgestellt, die eine Tabelle in einen Buchstaben umwandelt. Ein Text ist eine Folge von Zeichen; wenn das so ist, kann er in einem std::vector<char> gespeichert werden, und was die Lektion Vektoren über Folgen gelehrt hat, gälte für ihn. Nun verlangt man vom Text Operationen, die man von einer beliebigen Folge nicht verlangt: einen anderen Text an ihn anfügen, in ihm ein Wort suchen, ein Stück herausziehen, ihn auf einmal ausgeben. Daraus folgt ein eigener Typ, die Zeichenkette (String), std::string, aus dem Header <string>: ein Vektor von char im Dienst des Textes.

C++-Programm
#include <format>#include <print>#include <string>​int main(){    const std::string first{"Ada"};    std::string greeting{"Hallo, " + first};    greeting += '.';    std::println("{} ({} Zeichen)", greeting, greeting.size());    std::println("Erstes „{}“, letztes „{}“", greeting[0], greeting.back());    int spaces{0};    for (const char c : greeting) {        if (c == ' ') {            ++spaces;        }    }    std::println("Leerzeichen: {}", spaces);    const std::string code{std::format("{}-{:03}", "MAT", 7)};    std::println("{} {}", code, code == "MAT-007");}
Ausgabe
Hallo, Ada. (11 Zeichen)Erstes „H“, letztes „.“Leerzeichen: 1MAT-007 true

Zeile 7 erzeugt eine Zeichenkette aus einem Literal. Zeile 8 verkettet sie: Der Operator + zwischen einer Zeichenkette und einem Literal erzeugt eine neue Zeichenkette mit den Zeichen beider, eines hinter dem anderen. Zeile 9 fügt mit += ein Zeichen am Ende an, was ebenso mit einer Zeichenkette oder einem Literal geht. Der Rest ist das, was man schon von den Vektoren wusste: size() zählt die Zeichen (11, denn auch das Komma, das Leerzeichen und der Punkt sind Zeichen), greeting[0] ist das erste und back() das letzte, und die Schleife der Zeilen 13 bis 17 durchläuft die Zeichenkette Zeichen für Zeichen mit der bereichsbasierten Form aus der Lektion Schleifen. Wie der Vektor kennt eine Zeichenkette außerdem push_back, pop_back und empty, und die Bibliothek von GCC 15 prüft, wenn nicht optimiert wird, ihre Indizes bei operator[] (mit Optimierung verschwindet diese Prüfung).

Die beiden letzten Zeilen lösen ein, was die Lektion Mit Funktionen entwerfen angekündigt hat. std::format aus <format> nimmt dieselben Platzhalter wie std::println, mit denselben Formatangaben ({:03} füllt mit Nullen auf drei Ziffern auf), gibt das Ergebnis aber nicht aus, sondern liefert es als Zeichenkette zurück: So baut man einen Text, der danach gespeichert, verglichen oder an eine Funktion übergeben wird. Und == vergleicht zwei Zeichenketten nach ihrem Inhalt: Sie sind gleich, wenn sie dieselbe Größe und dieselben Zeichen in derselben Reihenfolge haben. Daher ist code == "MAT-007" gleich true, obwohl der linke Text stückweise gebaut wurde und der rechte ein Literal ist.

Vergleichen

Außer == und != kennen Zeichenketten <, <=, > und >=, die sie in lexikographischer Ordnung vergleichen, der Ordnung des Wörterbuchs: Man durchläuft beide gleichzeitig, und an der ersten Position, an der sie sich unterscheiden, entscheidet das kleinere Zeichen; ist eine ohne jeden Unterschied früher erschöpft, so ist die kürzere die kleinere. So ist die Zeichenkette „Mann“ kleiner als „Mond“, weil an der zweiten Position 'a' < 'o' gilt, und „Rat“ ist kleiner als „Rate“, weil die erste ein Präfix der zweiten ist. Die Operatoren vergleichen Zeichenketten: Zwischen zwei in Anführungszeichen geschriebenen Literalen vergleichen sie etwas anderes, denn ein Literal ist kein std::string, sondern ein Array, wie der Teil über die C-Strings zeigen wird. Welches Zeichen „kleiner“ ist, entscheidet sein Code, nicht das Alphabet; der letzte Teil der Lektion zeigt, was daraus folgt.