EMZETT.
Login

Kurz: Anders als in C ist std::string ein wachsender, verwalteter Text:

Teil des Kurses C++

Kapitel 5 von 15 im Kurs C++ (Abschnitt „Standardbibliothek“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

std::string

Anders als in C ist std::string ein wachsender, verwalteter Text:

#include <iostream>
#include <string>
#include <string_view>
#include <algorithm>
 
int main() {
    std::string s = "Hallo Welt";
    s += "!";
    std::cout << s << " " << s.size() << " " << s[0] << " " << s.at(1) << '\n';
    std::cout << s.substr(6, 4) << " " << s.find("Welt") << " " << (s.find("x") == std::string::npos) << '\n';
    s.replace(0, 5, "Servus");
    s.insert(s.size(), "!!");
    std::cout << s << '\n';
    std::string a = "abc", b = "abd";
    std::cout << (a < b) << (a == "abc") << ' ' << a + b << '\n';
    std::transform(a.begin(), a.end(), a.begin(), [](unsigned char c) { return std::toupper(c); });
    std::cout << a << ' ' << std::to_string(42) + "x" << ' ' << std::stoi("123") + 1 << ' ' << std::stod("2.5") * 2 << '\n';
    std::string_view sicht = s;                         // nur ansehen, nicht kopieren
    std::cout << sicht.substr(0, 6) << " " << s.starts_with("Servus") << '\n';   // C++20
    return 0;
}

Ausgabe:

Hallo Welt! 11 H a
Welt 6 1
Servus Welt!!!
11 abcabd
ABC 42x 124 5
Servus 1

std::string_view (C++17) ist eine leichte Sicht auf bestehenden Text ohne Kopie: ideal für Parameter, die nur lesen.

vector: das Standard-Array

#include <iostream>
#include <vector>
#include <algorithm>
 
int main() {
    std::vector<int> v{5, 3, 9};
    v.push_back(1);                       // hinten anhängen (wächst automatisch)
    v.insert(v.begin() + 1, 42);          // an Position einfügen
    std::cout << v.size() << ' ' << v.front() << ' ' << v.back() << ' ' << v[2] << ' ' << v.at(3) << '\n';
    v.pop_back();
    v.erase(v.begin());                   // erstes Element löschen
    std::sort(v.begin(), v.end());
    for (int x : v) std::cout << x << ' ';
    std::cout << '\n';
 
    std::vector<std::string> namen{"Mia", "Tom"};
    namen.emplace_back("Zoe");            // direkt im Vektor erzeugen
    std::vector<int> nullen(5, 0);        // fünf Nullen
    std::vector<std::vector<int>> matrix(2, std::vector<int>(3, 1));
    std::cout << namen.size() << nullen.size() << matrix[1][2] << '\n';
    try { v.at(99); } catch (const std::out_of_range& e) { std::cout << "außerhalb\n"; }
    return 0;
}

Ausgabe:

5 5 1 3 9
3 9 42
351
außerhalb

at(i) prüft die Grenze und wirft eine Ausnahme, [i] prüft nicht (schneller, aber UB bei Fehlern).

Weitere Container

ContainerEigenschaftTypische Nutzung
std::array<T, N>feste Größe, auf dem Stackkleine feste Felder
std::vector<T>wachsend, zusammenhängendStandardwahl
std::deque<T>vorn und hinten schnellWarteschlange
std::list<T>doppelt verkettetselten sinnvoll
std::set<T>, std::map<K,V>sortiert, Baumsortierte Mengen/Tabellen
std::unordered_set<T>, std::unordered_map<K,V>Hashtabelleschnelles Suchen
std::stack<T>, std::queue<T>, std::priority_queue<T>AdapterStapel, Schlange, Priorität
#include <iostream>
#include <map>
#include <unordered_map>
#include <set>
#include <string>
#include <queue>
#include <array>
 
int main() {
    std::map<std::string, int> alter;                 // sortiert nach Schlüssel
    alter["Tom"] = 19;
    alter["Mia"] = 17;
    alter.insert({"Zoe", 21});
    for (const auto& [name, jahre] : alter) std::cout << name << '=' << jahre << ' ';
    std::cout << '\n';
    if (auto it = alter.find("Mia"); it != alter.end()) std::cout << "gefunden " << it->second << '\n';
    std::cout << alter.count("Max") << alter.contains("Tom") << '\n';     // contains: C++20
 
    std::unordered_map<char, int> haeufig;
    for (char c : std::string("mississippi")) haeufig[c]++;
    std::cout << haeufig['s'] << haeufig['i'] << haeufig['p'] << '\n';
 
    std::set<int> menge{3, 1, 3, 2};
    std::cout << menge.size() << ' ' << *menge.begin() << '\n';
 
    std::priority_queue<int> pq;
    for (int x : {5, 1, 8, 3}) pq.push(x);
    std::cout << pq.top() << '\n';
 
    std::array<int, 3> fest{1, 2, 3};
    std::cout << fest.size() << fest[1] << '\n';
    return 0;
}

Ausgabe:

Mia=17 Tom=19 Zoe=21
gefunden 17
01
442
3 1
8
32

Achtung

map[key] legt einen fehlenden Schlüssel neu an (mit Standardwert). Zum bloßen Nachsehen nimm find, contains oder at.

Iteratoren

Iteratoren sind verallgemeinerte Zeiger auf Elemente. Container liefern sie mit begin() und end() (hinter das letzte Element). Algorithmen arbeiten mit Iterator-Paaren:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
 
int main() {
    std::vector<int> v{4, 8, 15, 16, 23, 42};
    auto it = std::find(v.begin(), v.end(), 15);
    std::cout << (it - v.begin()) << ' ' << *it << '\n';
    v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x % 2; }), v.end());    // Erase-Remove-Idiom
    for (int x : v) std::cout << x << ' ';
    std::cout << '\n';
    std::cout << std::reduce(v.begin(), v.end()) << ' ' << std::accumulate(v.begin(), v.end(), 1, [](int a, int b) { return a + b / 2; }) << '\n';
    std::reverse(v.begin(), v.end());
    std::list<int> l(v.begin(), v.end());
    std::cout << l.front() << l.back() << '\n';
    std::erase_if(v, [](int x) { return x > 30; });                     // C++20: kürzer
    std::cout << v.size() << '\n';
    return 0;
}

Ausgabe:

2 15
4 8 16 42
70 36
424
3

Welcher Container?

  1. Im Zweifel std::vector. Er ist cachefreundlich und meist am schnellsten
  2. Schlüssel → Wert: std::unordered_map (schnell) oder std::map (sortiert)
  3. Duplikate entfernen / Mengen: std::set oder std::unordered_set
  4. Feste kleine Größe: std::array
  5. Warteschlange: std::deque oder std::queue

Merke

  • std::string verwaltet Text selbst; std::string_view ist eine kopierfreie Sicht
  • std::vector ist der Standardcontainer: push_back, size, at, erase
  • map/set sortiert, unordered_map/unordered_set per Hash
  • map[key] legt fehlende Schlüssel an: find/contains zum Suchen
  • Iteratoren (begin(), end()) verbinden Container mit Algorithmen

Übungsaufgabe

Zähle die Häufigkeit der Wörter in einem Satz mit std::map und gib die Wörter sortiert mit ihrer Anzahl aus.

Quiz zur Selbstkontrolle

für einen fehlenden Schlüssel?

  • Legt den Eintrag mit Standardwert neu an (richtig)
  • Wirft immer eine Ausnahme
  • Gibt nullptr zurück
  • Ignoriert den Zugriff

Weiter im Kurs

Zurück: Funktionen, Lambdas und constexpr

Weiter: Klassen und Objekte

Alle Kapitel: C++ im Überblick