Suche…


Einführung

Strings sind Objekte, die Zeichenfolgen darstellen. Die Standard - string - Klasse bietet eine einfache, sichere und vielseitige Alternative zu explizitem Arrays mit char s , wenn sie mit Text und anderen Zeichenfolge handeln. Die C ++ - string Klasse ist Teil des std Namespaces und wurde 1998 standardisiert.

Syntax

  • // Leere String-Deklaration

    std :: string s;

  • // Konstruieren aus const char * (C-String)

    std :: string s ("Hallo");

    std :: string s = "Hallo";

  • // Konstruieren mit dem Copy-Konstruktor

    std :: string s1 ("Hallo");

    std :: string s2 (s1);

  • // Konstruieren aus Teilzeichenfolge

    std :: string s1 ("Hallo");

    std :: string s2 (s1, 0, 4); // Kopiere 4 Zeichen von Position 0 von s1 nach s2

  • // Konstruieren aus einem Zeichenpuffer

    std :: string s1 ("Hallo Welt");
    std :: string s2 (s1, 5); // Kopiere die ersten 5 Zeichen von s1 in s2

  • // Konstruieren mit Füllkonstruktor (nur Zeichen)

    std :: string s (5, 'a'); // s enthält aaaaa

  • // Konstruieren mit Range-Konstruktor und Iterator

    std :: string s1 ("Hallo Welt");

    std :: string s2 (s1.begin (), s1.begin () + 5); // Kopiere die ersten 5 Zeichen von s1 in s2

Bemerkungen

Bevor Sie std::string , sollten Sie den Header- string einschließen, da er Funktionen / Operatoren / Überladungen enthält, die andere Header (z. B. iostream ) nicht enthalten.


Die Verwendung von const char * constructor mit einem nullptr führt zu undefiniertem Verhalten.

std::string oops(nullptr);
std::cout << oops << "\n";

Die Methode at std::out_of_range Ausnahme für std::out_of_range wenn index >= size() .

Das Verhalten von operator[] ist etwas komplizierter, in allen Fällen hat es undefiniertes Verhalten, wenn index > size() , aber wenn index == size() :

C ++ 11
  1. Bei einer nicht konstanten Zeichenfolge ist das Verhalten undefiniert .
  2. In einer const-Zeichenfolge wird ein Verweis auf ein Zeichen mit dem Wert CharT() (das Nullzeichen ) zurückgegeben.
C ++ 11
  1. Ein Verweis auf ein Zeichen mit dem Wert CharT() (das Nullzeichen ) wird zurückgegeben.
  2. Das Ändern dieser Referenz ist undefiniertes Verhalten .

Seit C ++ 14 wird anstelle von "foo" empfohlen, "foo"s , da s ein benutzerdefiniertes literales Suffix ist , das das const char* "foo" in std::string "foo" konvertiert. .

Hinweis: Sie müssen den Namespace std::string_literals oder std::literals std::string_literals , um das Literal s .

Aufteilen

Verwenden Sie std::string::substr , um eine Zeichenfolge zu teilen. Es gibt zwei Varianten dieser Member-Funktion.

Der erste nimmt eine Startposition ein, von der aus der zurückgegebene Teilstring beginnen sollte. Die Startposition muss im Bereich (0, str.length()] gültig sein:

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"

Der zweite nimmt eine Startposition und die Gesamtlänge des neuen Teilstrings ein. Unabhängig von der Länge wird die Teilzeichenfolge niemals über das Ende der Quellzeichenfolge hinausgehen:

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"

Beachten Sie, dass Sie substr ohne Argumente aufrufen können. In diesem Fall wird eine genaue Kopie der Zeichenfolge zurückgegeben

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"

String ersetzen

Durch Position ersetzen

Um einen Teil eines std::string zu ersetzen, können Sie die Methode replace von std::string .

replace hat viele nützliche Überladungen:

//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";

//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"

//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"

//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
C ++ 14
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"

//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"

//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
C ++ 11
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"

Ersetzen Sie Vorkommen einer Zeichenfolge durch eine andere Zeichenfolge

Ersetze nur das erste Vorkommen von replace mit with in str :

std::string replaceString(std::string str,
                          const std::string& replace,
                          const std::string& with){
    std::size_t pos = str.find(replace);
    if (pos != std::string::npos)
        str.replace(pos, replace.length(), with);
    return str;
}

Ersetzen Sie alle Vorkommen von replace durch with in str :

std::string replaceStringAll(std::string str,
                             const std::string& replace,
                             const std::string& with) {
    if(!replace.empty()) {
        std::size_t pos = 0;
        while ((pos = str.find(replace, pos)) != std::string::npos) {
            str.replace(pos, replace.length(), with);
            pos += with.length();
        }
    }
    return str;
}

Verkettung

Sie können std::string s mit den überladenen Operatoren + und += verketten. Mit dem Operator + :

std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"

Verwenden des Operators += :

std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"

Sie können auch C-Strings anhängen, einschließlich String-Literalen:

std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"

Sie können auch verwenden push_back() einzelne zurückdrängen char s:

std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"

Es gibt auch append() , was ziemlich ähnlich ist wie += :

std::string app = "test and ";
app.append("test"); // "test and test"

Zugriff auf einen Charakter

Es gibt mehrere Möglichkeiten, Zeichen aus einem std::string zu extrahieren, und jede ist unterschiedlich.

std::string str("Hello world!");

Operator [] (n)

Gibt eine Referenz auf das Zeichen am Index n zurück.

std::string::operator[] wird nicht auf Grenzen geprüft und löst keine Ausnahme aus. Der Aufrufer ist dafür verantwortlich, dass der Index im Bereich der Zeichenfolge liegt:

char c = str[6]; // 'w'

bei (n)

Gibt eine Referenz auf das Zeichen am Index n zurück.

std::string::at wird auf Grenzen geprüft und gibt std::out_of_range wenn der Index nicht im Bereich des Strings liegt:

char c = str.at(7); // 'o'
C ++ 11

Anmerkung: Beide Beispiele führen zu undefiniertem Verhalten, wenn die Zeichenfolge leer ist.


Vorderseite()

Gibt eine Referenz auf das erste Zeichen zurück:

char c = str.front(); // 'H'

zurück()

Gibt eine Referenz auf das letzte Zeichen zurück:

char c = str.back(); // '!'

Tokenize

Gelistet von den billigsten zur teuersten zur Laufzeit:

  1. str::strtok ist die billigste standardisierte Tokenisierungsmethode. Sie ermöglicht auch die Änderung des Trennzeichens zwischen Tokens, verursacht jedoch 3 Probleme mit modernem C ++:

    • std::strtok kann nicht gleichzeitig für mehrere strings werden (obwohl einige Implementierungen dies unterstützen, z. strtok_s .: strtok_s )
    • Aus demselben Grund kann std::strtok nicht gleichzeitig auf mehreren Threads verwendet werden (dies kann jedoch durch die Implementierung definiert werden, z. B.: Die Implementierung von Visual Studio ist threadsicher ).
    • Durch Aufrufen von std::strtok der std::string er arbeitet, std::strtok kann er nicht für const string s, const char* s oder literal strings verwendet werden, um eine dieser Zeichenketten mit std::strtok zu std::strtok oder eine std::string dessen Inhalt muss erhalten bleiben, die Eingabe müsste kopiert werden, dann könnte die Kopie bearbeitet werden

    Im Allgemeinen werden diese Optionen in den Zuweisungskosten der Token versteckt. Wenn jedoch der billigste Algorithmus erforderlich ist und die Schwierigkeiten von std::strtok nicht übermäßig sind, sollten Sie eine von Hand gesponnene Lösung in Betracht ziehen.

// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;

for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
    tokens.push_back(i);

Live-Beispiel

  1. Der std::istream_iterator verwendet den Extraktionsoperator des Streams iterativ. Wenn die Eingabe std::string Leerzeichen getrennt ist, kann die Option std::strtok durch Beseitigung der Schwierigkeiten erweitert werden, wodurch die Inline-Tokenisierung ermöglicht wird, wodurch die Erzeugung eines const vector<string> , und indem Unterstützung für mehrere hinzugefügt wird Leerzeichen abgrenzend:
// String to tokenize
const std::string str("The  quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
                                        std::istream_iterator<std::string>(is),
                                        std::istream_iterator<std::string>());

Live-Beispiel

  1. Der std::regex_token_iterator verwendet einen std::regex um iterativ zu tokenisieren. Es bietet eine flexiblere Definition von Begrenzungszeichen. Beispiel: Nicht begrenzte Kommas und Leerzeichen:
C ++ 11
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{ 
    std::sregex_token_iterator(str.begin(), str.end(), re, 1), 
    std::sregex_token_iterator() 
};

Live-Beispiel

Weitere regex_token_iterator Sie im regex_token_iterator Beispiel .

Konvertierung in (const) char *

Um mit const char* auf die Daten einer std::string zuzugreifen, können Sie die c_str() der Zeichenfolge verwenden. Beachten Sie, dass der Zeiger nur gültig ist, solange sich das Objekt std::string im Gültigkeitsbereich befindet und unverändert bleibt. Dies bedeutet, dass nur const Methoden für das Objekt aufgerufen werden können.

C ++ 17

Die data() Memberfunktion kann verwendet werden, um ein modifizierbares char* , mit dem die Daten des std::string Objekts bearbeitet werden können.

C ++ 11

Ein modifizierbares Zeichen char* kann auch erhalten werden, indem die Adresse des ersten Zeichens verwendet wird: &s[0] . In C ++ 11 wird garantiert, dass dies eine wohlgeformte, nullterminierte Zeichenfolge ergibt. Beachten Sie, dass &s[0] dann gut geformt ist, wenn s leer ist, wohingegen &s.front() undefined ist, wenn s leer ist.

C ++ 11
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data();  // data points to: "This is a string.\0"
std::string str("This is a string.");

// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);

// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];

std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added

// delete[] cstr_unsafe;
std::cout << cstr.get();

Zeichen in einer Zeichenfolge finden

Um ein Zeichen oder eine andere Zeichenfolge zu finden, können Sie std::string::find . Es gibt die Position des ersten Zeichens des ersten Matches zurück. Wenn keine Übereinstimmungen gefunden wurden, gibt die Funktion std::string::npos

std::string str = "Curiosity killed the cat";
auto it = str.find("cat");

if (it != std::string::npos)
    std::cout << "Found at position: " << it << '\n';
else
    std::cout << "Not found!\n";

Gefunden an Position: 21


Die Suchmöglichkeiten werden um folgende Funktionen erweitert:

find_first_of     // Find first occurrence of characters 
find_first_not_of // Find first absence of characters 
find_last_of      // Find last occurrence of characters 
find_last_not_of  // Find last absence of characters 

Mit diesen Funktionen können Sie am Ende der Zeichenfolge nach Zeichen suchen und den negativen Fall (dh Zeichen, die nicht in der Zeichenfolge enthalten sind) finden. Hier ist ein Beispiel:

std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';

Gefunden an Position: 6

Hinweis: Beachten Sie, dass die oben genannten Funktionen nicht nach Teilzeichenfolgen suchen, sondern nach Zeichen, die in der Suchzeichenfolge enthalten sind. In diesem Fall wurde das letzte Vorkommen von 'g' an Position 6 (die anderen Zeichen wurden nicht gefunden).

Zeichen am Anfang / Ende abschneiden

In diesem Beispiel sind die Header <algorithm> , <locale> und <utility> erforderlich.

C ++ 11

Um eine Sequenz oder String trim bedeutet alle vorderen und hinteren Elemente (oder Zeichen) zu entfernen , um ein bestimmtes Prädikat übereinstimmt. Wir schneiden zuerst die nachlaufenden Elemente ab, da keine Elemente bewegt werden müssen, und dann die führenden Elemente. Beachten Sie, dass die folgenden Verallgemeinerungen für alle Arten von std::basic_string (z. B. std::string und std::wstring ) und aus Versehen auch für std::basic_string (z. B. std::vector und std::list ) std::wstring .

template <typename Sequence, // any basic_string, vector, list etc.
          typename Pred>     // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
    return trim_start(trim_end(seq, pred), pred);
}

Beim Trimmen der nachfolgenden Elemente wird das letzte Element gefunden, das nicht mit dem Vergleichselement übereinstimmt, und von dort aus gelöscht:

template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
    auto last = std::find_if_not(seq.rbegin(),
                                 seq.rend(),
                                 pred);
    seq.erase(last.base(), seq.end());
    return seq;
}

Beim Trimmen der führenden Elemente wird das erste Element gefunden, das nicht mit dem Prädikat übereinstimmt, und bis dahin gelöscht:

template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
    auto first = std::find_if_not(seq.begin(),
                                  seq.end(),
                                  pred);
    seq.erase(seq.begin(), first);
    return seq;
}

Um das Obige auf das Trimmen von Whitespace in einem std::string , können wir die Funktion std::isspace() als Prädikat verwenden:

std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
    return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
    return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
    return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}

In ähnlicher Weise können wir die Funktion std::iswspace() für std::wstring usw. verwenden.

Wenn Sie eine neue Sequenz erstellen möchten, die eine zugeschnittene Kopie ist, können Sie eine separate Funktion verwenden:

template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
    trim(seq, pred);
    return seq;
}

Lexikographischer Vergleich

Zwei std::string s können lexikographisch mit den Operatoren == != , < , <= , > Und >= verglichen werden:

std::string str1 = "Foo";
std::string str2 = "Bar";

assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);

Alle diese Funktionen verwenden die zugrunde liegende Methode std::string::compare() , um den Vergleich durchzuführen und zur Vereinfachung boolesche Werte zurückzugeben. Die Funktionsweise dieser Funktionen kann unabhängig von der tatsächlichen Implementierung wie folgt interpretiert werden:

  • Operator == :

    Wenn str1.length() == str2.length() und jedes Zeichenpaar übereinstimmt, wird true , andernfalls false .

  • Operator != :

    Wenn str1.length() != str2.length() oder ein Zeichenpaar nicht übereinstimmt, wird true , andernfalls false .

  • Operator < oder Operator > :

    Findet das erste unterschiedliche Zeichenpaar, vergleicht sie und gibt das boolesche Ergebnis zurück.

  • Operator <= oder Operator >= :

    Findet das erste unterschiedliche Zeichenpaar, vergleicht sie und gibt das boolesche Ergebnis zurück.

Hinweis: Unter dem Begriff Zeichenpaar sind die entsprechenden Zeichen in beiden Zeichenfolgen derselben Position zu verstehen. Zum besseren Verständnis str1 , wenn zwei Beispielketten str1 und str2 sind und ihre Längen jeweils n und m sind, die Zeichenpaare beider Strings jeweils str1[i] und str2[i] Paare, wobei i = 0, 1, 2 str2[i] .., max (n, m) . Wenn für ein i, wenn das entsprechende Zeichen nicht existiert, das heißt, wenn i größer als oder gleich n oder m , würde es als der niedrigste Wert betrachtet werden.


Hier ist ein Beispiel für die Verwendung von < :

std::string str1 = "Barr";
std::string str2 = "Bar";

assert(str2 < str1);

Die Schritte sind wie folgt:

  1. Vergleichen Sie die ersten Zeichen, 'B' == 'B' - fahren Sie fort.
  2. Vergleichen Sie die zweiten Zeichen, 'a' == 'a' - weiter.
  3. Vergleichen Sie die dritten Zeichen, 'r' == 'r' - fahren Sie fort.
  4. Der str2 Bereich ist jetzt erschöpft, während der str1 Bereich noch Zeichen enthält. Somit ist str2 < str1 .

Konvertierung in std :: wstring

In C ++ werden Zeichenfolgen dargestellt, indem die Klasse std::basic_string auf einen nativen Zeichentyp spezialisiert wird. Die zwei Hauptsammlungen, die von der Standardbibliothek definiert werden, sind std::string und std::wstring :

  • std::string wird mit Elementen des Typs char

  • std::wstring besteht aus Elementen des Typs wchar_t

Um zwischen den beiden Typen zu konvertieren, verwenden Sie wstring_convert :

#include <string>
#include <codecvt>
#include <locale>

std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";

// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);

std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);

Um die Benutzerfreundlichkeit und / oder Lesbarkeit zu verbessern, können Sie Funktionen zur Durchführung der Konvertierung definieren:

#include <string>
#include <codecvt>
#include <locale>

using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;

std::string to_string(std::wstring wstr)
{
    return strconverter.to_bytes(wstr);
}

std::wstring to_wstring(std::string str)
{
    return strconverter.from_bytes(str);
}

Verwendungsbeispiel:

std::wstring a_wide_string = to_wstring("Hello World!");

Das ist sicherlich lesbarer als std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!") .


Bitte beachten Sie, dass char und wchar_t keine Kodierung implizieren und keine Angabe der Größe in Byte enthalten. Beispielsweise ist wchar_t im Allgemeinen als 2-Byte-Datentyp implementiert und enthält in der Regel UTF-16-codierte Daten unter Windows (oder UCS-2 in Versionen vor Windows 2000) und als 4-Byte-Datentyp, der mit UTF-32 unter codiert ist Linux. Dies steht im Gegensatz zu den neueren Typen char16_t und char32_t , die in C ++ 11 eingeführt wurden und die garantiert groß genug sind, um UTF16- oder UTF32-Zeichen (oder genauer Codepunkt ) aufzunehmen.

Verwenden der Klasse std :: string_view

C ++ 17

In C ++ 17 wird std::string_view , bei dem es sich einfach um einen nicht besitzenden Bereich von const char std::string_view , der entweder als Zeigerpaar oder als Zeiger und als Länge implementiert werden kann. Dies ist ein überlegener Parametertyp für Funktionen, für die nicht modifizierbare Zeichenfolgendaten erforderlich sind. Vor C ++ 17 gab es dafür drei Möglichkeiten:

void foo(std::string const& s);      // pre-C++17, single argument, could incur
                                     // allocation if caller's data was not in a string
                                     // (e.g. string literal or vector<char> )

void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
                                     // both everywhere

void foo(const char* s);             // pre-C++17, single argument, but need to call
                                     // strlen()

template <class StringT>
void foo(StringT const& s);          // pre-C++17, caller can pass arbitrary char data
                                     // provider, but now foo() has to live in a header

Alle diese können ersetzt werden durch:

void foo(std::string_view s);        // post-C++17, single argument, tighter coupling
                                     // zero copies regardless of how caller is storing
                                     // the data

Beachten Sie, dass std::string_view die zugrunde liegenden Daten nicht ändern kann .

string_view ist nützlich, wenn Sie unnötige Kopien vermeiden möchten.

Es bietet eine nützliche Untermenge der Funktionalität, die von std::string wird, obwohl einige Funktionen sich unterschiedlich verhalten:

std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string

//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';

//Good way - No copies are created!
std::string_view view = str;

// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';

Durchlaufen jedes Charakters

C ++ 11

std::string unterstützt Iteratoren. Daher können Sie eine range-basierte Schleife verwenden, um jedes Zeichen zu durchlaufen:

std::string str = "Hello World!";
for (auto c : str)
    std::cout << c;

Sie können eine "traditionelle" for Schleife verwenden, um jedes Zeichen zu durchlaufen:

std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
    std::cout << str[i];

Konvertierung in Ganzzahlen / Gleitkommatypen

Ein std::string , der eine Zahl enthält, kann mithilfe von Konvertierungsfunktionen in einen Integer-Typ oder einen Gleitkommatyp konvertiert werden.

Beachten Sie, dass alle diese Funktionen die Analyse der Eingabezeichenfolge beenden, sobald sie auf ein nicht numerisches Zeichen stoßen, so dass "123abc" in 123 .


Die Funktionsfamilie std::ato* konvertiert Zeichenketten im C-Stil (Zeichenarrays) in Ganzzahl- oder Fließkommatypen:

std::string ten = "10";

double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
C ++ 11
long long num4 = std::atoll(ten.c_str());

Die Verwendung dieser Funktionen wird jedoch nicht empfohlen, da sie 0 wenn die Zeichenfolge nicht analysiert werden kann. Dies ist schlecht, da 0 auch ein gültiges Ergebnis sein kann, wenn die Eingabezeichenfolge beispielsweise "0" war. Daher kann nicht festgestellt werden, ob die Konvertierung tatsächlich fehlgeschlagen ist.

Die neuere Funktionsfamilie std::sto* konvertiert std::string s in Ganzzahl- oder Fließkommatypen und löst Ausnahmen aus, wenn sie ihre Eingabe nicht analysieren konnten. Sie sollten diese Funktionen nach Möglichkeit verwenden :

C ++ 11
std::string ten = "10";

int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);

float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);

Darüber hinaus behandeln diese Funktionen im Gegensatz zur std::ato* -Familie auch Oktal- und Hex-Strings. Der zweite Parameter ist ein Zeiger auf das erste nicht konvertierte Zeichen in der Eingabezeichenfolge (hier nicht dargestellt), und der dritte Parameter ist die zu verwendende Basis. 0 ist die automatische Erkennung von Oktal (beginnend mit 0 ) und Hex (beginnend mit 0x oder 0X ), und jeder andere Wert ist die zu verwendende Basis

std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";

int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16);  // Returns 10
long num4 = std::stol(ten_hex);  // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x

Konvertierung zwischen Zeichenkodierungen

Das Konvertieren zwischen Codierungen ist mit C ++ 11 einfach und die meisten Compiler können plattformübergreifend mit den <codecvt> und <locale> <codecvt> .

#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;

int main() {
    // converts between wstring and utf8 string
    wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
    // converts between u16string and utf8 string
    wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
    
    wstring wstr = L"foobar";
    string utf8str = wchar_to_utf8.to_bytes(wstr);
    wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
    
    wcout << wstr << endl;
    cout << utf8str << endl;
    wcout << wstr2 << endl;
    
    u16string u16str = u"foobar";
    string utf8str2 = utf16_to_utf8.to_bytes(u16str);
    u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
    
    return 0;
}

Beachten Sie, dass Visual Studio 2015 Unterstützung für diese Konvertierung bietet. Ein Fehler in der Bibliotheksimplementierung erfordert die Verwendung einer anderen Vorlage für wstring_convert wenn mit char16_t :

using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;

void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
  std::basic_string<utf16_char> tmp;
  tmp.resize(utf16.length());
  std::copy(utf16.begin(), utf16.end(), tmp.begin());
  utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{ 
  std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
  utf16.clear();
  utf16.resize(tmp.length());
  std::copy(tmp.begin(), tmp.end(), utf16.begin());
}

Prüfen, ob eine Zeichenfolge ein Präfix einer anderen ist

C ++ 14

In C ++ 14 kann dies problemlos mit std::mismatch wobei das erste Paar aus zwei Bereichen das nicht übereinstimmende Paar zurückgibt:

std::string prefix = "foo";
std::string string = "foobar";

bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
    string.begin(), string.end()).first == prefix.end();

Beachten Sie, dass vor Andern von C ++ 14 eine anderthalbminütige Version von mismatch() vorhanden war. Dies ist jedoch nicht sicher, wenn die zweite Zeichenfolge die kürzere der beiden ist.

C ++ 14

Wir können immer noch die Range-and-a-half-Version von std::mismatch() , aber wir müssen zuerst prüfen, ob der erste String höchstens so groß ist wie der zweite:

bool isPrefix = prefix.size() <= string.size() &&
    std::mismatch(prefix.begin(), prefix.end(),
        string.begin(), string.end()).first == prefix.end();
C ++ 17

Mit std::string_view können wir den gewünschten direkten Vergleich schreiben, ohne sich um den Zuordnungsaufwand oder das std::string_view Kopien kümmern zu müssen:

bool isPrefix(std::string_view prefix, std::string_view full)
{
    return prefix == full.substr(0, prefix.size());
}

Konvertierung in std :: string

std::ostringstream kann jeder Streamable-Typ in eine String-Darstellung konvertiert werden, indem das Objekt in ein std::ostringstream Objekt std::ostringstream wird (mit dem Stream-Einfügungsoperator << ) und anschließend der gesamte std::ostringstream in einen std::string konvertiert wird std::string .

Für int zum Beispiel:

#include <sstream>

int main()
{
    int val = 4;
    std::ostringstream str;
    str << val;
    std::string converted = str.str();
    return 0;
}

Schreiben Sie Ihre eigene Konvertierungsfunktion:

template<class T>
std::string toString(const T& x)
{
  std::ostringstream ss;
  ss << x;
  return ss.str();
}

funktioniert, ist jedoch nicht für leistungskritischen Code geeignet.

Benutzerdefinierte Klassen können den Stream-Einfügeoperator implementieren, falls dies gewünscht ist:

std::ostream operator<<( std::ostream& out, const A& a )
{
    // write a string representation of a to out
    return out; 
}
C ++ 11

Abgesehen von Streams können Sie seit C ++ 11 auch die Funktion std::to_string (und std::to_wstring ) verwenden, die für alle grundlegenden Typen überladen ist und die String-Darstellung ihres Parameters zurückgibt.

std::string s = to_string(0x12f3);  // after this the string s contains "4851"


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow