C++
std :: string
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()
:
- Bei einer nicht konstanten Zeichenfolge ist das Verhalten undefiniert .
- In einer const-Zeichenfolge wird ein Verweis auf ein Zeichen mit dem Wert
CharT()
(das Nullzeichen ) zurückgegeben.
- Ein Verweis auf ein Zeichen mit dem Wert
CharT()
(das Nullzeichen ) wird zurückgegeben. - 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!"
//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!"
//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'
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:
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 mehrerestrings
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
derstd::string
er arbeitet,std::strtok
kann er nicht fürconst string
s,const char*
s oder literal strings verwendet werden, um eine dieser Zeichenketten mitstd::strtok
zustd::strtok
oder einestd::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);
- Der
std::istream_iterator
verwendet den Extraktionsoperator des Streams iterativ. Wenn die Eingabestd::string
Leerzeichen getrennt ist, kann die Optionstd::strtok
durch Beseitigung der Schwierigkeiten erweitert werden, wodurch die Inline-Tokenisierung ermöglicht wird, wodurch die Erzeugung einesconst 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>());
- Der
std::regex_token_iterator
verwendet einenstd::regex
um iterativ zu tokenisieren. Es bietet eine flexiblere Definition von Begrenzungszeichen. Beispiel: Nicht begrenzte Kommas und Leerzeichen:
// 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()
};
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.
Die data()
Memberfunktion kann verwendet werden, um ein modifizierbares char*
, mit dem die Daten des std::string
Objekts bearbeitet werden können.
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.
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.
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, wirdtrue
, andernfallsfalse
.Operator
!=
:Wenn
str1.length() != str2.length()
oder ein Zeichenpaar nicht übereinstimmt, wirdtrue
, andernfallsfalse
.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:
- Vergleichen Sie die ersten Zeichen,
'B' == 'B'
- fahren Sie fort. - Vergleichen Sie die zweiten Zeichen,
'a' == 'a'
- weiter. - Vergleichen Sie die dritten Zeichen,
'r' == 'r'
- fahren Sie fort. - Der
str2
Bereich ist jetzt erschöpft, während derstr1
Bereich noch Zeichen enthält. Somit iststr2 < 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 Typschar
std::wstring
besteht aus Elementen des Typswchar_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
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
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());
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 :
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
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.
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();
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;
}
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"