Strings, the C++ way

C++ bietet eine Sammlung von String-Klassen für verschiedene Anwendungsfälle, die sich letzten Endes alle auf das gleiche Template zurückführen lassen: std::basic_string.

Video

Quellcode

#include <iostream>
#include <string>

using namespace std;

int main()
{
  string      s {   "Ein kleiner Test-String......" };
  string     us { u8"UTF-8 geht auch. So halb: äöü" };
  wstring    ws {  L"Das ganze als Wide-String...." };
  u16string s16 {  u"Und als char16_t-Variante...." };
  u32string s32 {  U"Zuguterletzt: char32_t......." };
  
  cout  << "  s(size=" << s.size()   << "): " << s << std::endl;
  cout  << " us(size=" << us.size()  << "): " << us << std::endl;
  wcout << " ws(size=" << ws.size()  << "): " << ws << std::endl;
  cout  << "s16(size=" << s16.size() << ")\n";
  cout  << "s32(size=" << s32.size() << ")\n";

  ws += L" mit noch was hinten ran";
  wcout << ws << std::endl;
  
  auto pos = ws.find(L"hinten");
  wcout << L"Ab Position " << pos << R"(: ")" << ws.substr(pos) << R"(")" << std::endl;
  
  basic_string<char> bs { "So sieht std::string eigentlich aus: " };
  bs += s;
  cout << bs << std::endl;
}

Erklärung

std::string dürfte die meistverwendete String-Klasse in C++ sein. Sie ist eine Instanz von std::basic_string für den Zeichentyp char, speichert also 8-Bit-Buchstaben. Initialisiert werden können deren Objekte beispielsweise aus String-Literalen vom Typ const char *, also "normalen" (ohne Präfix) und u8-Literalen. Für die u8-Literale bleibt allerdings das gleiche Problem, wie bei std::char_traits<char>::length() bestehen: std::size() liefert die Anzahl an Characters. Da in UTF-8 alle Zeichen oberhalb von ASCII-Code 127 (also bspw. auch alle Umlaute) aus mehr als einem Byte bestehen, stimmen die Anzahl an Buchstaben im String und die Anzahl an gespeicherten Zeichen nicht überein. Einfach mal so schnell die Länge feststellen geht so also nicht.

Es gibt aus passende Instanziierung von std::basic_string für wchar_t (wstring), char16_t (u16string) und char32_t (u32string). Alle bieten die gleiche Schnittstelle, arbeiten aber eben auf Basis der entsprechenden Literale. Leider sind die String-Klassen nicht so einfach kompatibel. Man kann also bspw. einen wstring und einen string nicht ohne weiteres aneinander hängen. 

C++ bietet auch zwei verschiedene Ausgabeströme an: std::cout für char-Strings und std::wcout für wchar_t-Strings. char16_t und char32_t sind leider ohne Umwandlung außen vor. Ob das Absicht ist oder ob da im Zuge von C++14 noch Änderungen kommen, bleibt abzuwarten.

Zeile 23 und 24 zeigen, wie man in C++-Strings suchen und Teilstrings erzeugen kann. std::string::find() liefert die Position, an der der gesuchte String beginnt oder std::string::npos, falls das gesuchte nicht gefunden werden kann. Mittels std::string::substr() kann man sich Teile eines Strings zurückliefern lassen. Aufgerufen ohne Parameter liefert die Methode den kompletten String, mit einem Parameter ab dieser Position bis zum Ende und mit zwei Parameter von der ersten, bis zu zweiten Position.