Sök…


Introduktion

Strängar är objekt som representerar sekvenser av tecken. Standarden string klassen ger en enkel, säker och mångsidig alternativ till att använda explicita arrayer av char s när det handlar om text och andra sekvenser av tecken. C ++ string är en del av std namnutrymmet och standardiserades i 1998.

Syntax

  • // Tom strängdeklaration

    std :: sträng s;

  • // Konstruera från const char * (c-string)

    std :: string s ("Hej");

    std :: string s = "Hej";

  • // Konstruktion med kopieringskonstruktör

    std :: string s1 ("Hej");

    std :: sträng s2 (s1);

  • // Konstruktion från substring

    std :: string s1 ("Hej");

    std :: sträng s2 (s1, 0, 4); // Kopiera 4 tecken från position 0 på s1 till s2

  • // Konstruera från en buffert med tecken

    std :: string s1 ("Hello World");
    std :: sträng s2 (s1, 5); // Kopiera de första 5 tecknen i s1 till s2

  • // Konstruera med fyllkonstruktor (endast char)

    std :: sträng s (5, 'a'); // s innehåller aaaaa

  • // Konstruera med hjälp av avståndskonstruktör och iterator

    std :: string s1 ("Hello World");

    std :: string s2 (s1.begin (), s1.begin () + 5); // Kopiera de första 5 tecknen i s1 till s2

Anmärkningar

Innan du använder std::string , bör du inkludera string , eftersom det innehåller funktioner / operatörer / överbelastning som andra huvuden (till exempel iostream ) ingår inte.


Att använda const char * -konstruktör med en nullptr leder till odefinierat beteende.

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

Metoden at kastar ett std::out_of_range undantag om index >= size() .

operator[] beteende är lite mer komplicerat, i alla fall har det odefinierat beteende om index > size() , men när index == size() :

C ++ 11
  1. På en icke-const-sträng är beteendet odefinierat ;
  2. På en const-sträng returneras en hänvisning till ett tecken med värdet CharT() ( nolltecknet ).
C ++ 11
  1. En referens till ett tecken med värdet CharT() ( nolltecknet ) returneras.
  2. Att ändra denna referens är odefinierat beteende .

Eftersom C ++ 14, istället för att använda "foo" , rekommenderas det att använda "foo"s , eftersom s är ett användardefinierat bokstavssuffix , som konverterar const char* "foo" till std::string "foo" .

Obs! Du måste använda namespace std::string_literals eller std::literals att få bokstav s .

delning

Använd std::string::substr att dela en sträng. Det finns två varianter av denna medlemsfunktion.

Den första tar en utgångsposition från vilken den returnerade substansen bör börja. Startpositionen måste vara giltig inom intervallet (0, str.length()] :

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

Den andra tar en startposition och en total längd på den nya substansen. Oavsett längd kommer substersträngen aldrig att gå förbi slutet på källsträngen:

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

Observera att du också kan ringa substr utan argument, i detta fall returneras en exakt kopia av strängen

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

Strängbyte

Byt ut efter position

För att ersätta en del av en std::string du använda metoden replace från std::string .

replace har många användbara överbelastningar:

//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!"

Byt ut förekomster av en sträng med en annan sträng

Ersätt bara den första förekomsten av replace med with i 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;
}

Byt ut all förekomst av replace med with i 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;
}

sammanlänkning

Du kan sammanfoga std::string med de överbelastade + och += operatörerna. Använda + operatören:

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

Med hjälp av += operatören:

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

Du kan också lägga till C-strängar, inklusive strängbokstäver:

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

Du kan också använda push_back() att trycka tillbaka enskilda char :

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

Det finns också append() , som gillar ungefär += :

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

Åtkomst till en karaktär

Det finns flera sätt att extrahera tecken från en std::string och var och en är subtilt olika.

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

Operatören [] (n)

Returnerar en referens till tecknet vid index n.

std::string::operator[] är inte gränskontrollerad och kastar inte ett undantag. Den som ringer är ansvarig för att hävda att indexet ligger inom strängområdet:

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

vid (n)

Returnerar en referens till tecknet vid index n.

std::string::at är gränserna kontrollerade, och kommer att kasta std::out_of_range om indexet inte ligger inom strängområdet:

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

Obs: Båda dessa exempel leder till odefinierat beteende om strängen är tom.


främre()

Returnerar en referens till det första tecknet:

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

tillbaka()

Returnerar en referens till det sista tecknet:

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

tokenize

Listas från billigast till dyrast vid körning:

  1. str::strtok är den billigaste metoden som tillhandahålls tokeniseringsmetod, den tillåter också avgränsaren att ändras mellan token, men den har tre svårigheter med modern C ++:

    • std::strtok kan inte användas på flera strings samtidigt (även om vissa implementationer sträcker sig för att stödja detta, till exempel: strtok_s )
    • Av samma anledning kan std::strtok inte användas på flera trådar samtidigt (detta kan emellertid definieras implementering, till exempel: Visual Studios implementering är trådsäker )
    • Att ringa std::strtok ändrar std::string den arbetar på, så det kan inte användas på const string s, const char* s eller bokstavliga strängar, för att symbolisera något av dessa med std::strtok eller för att fungera på en std::string veminnehåll måste bevaras, ingången måste kopieras, då kan kopian användas

    I allmänhet kommer något av dessa alternativskostnader att döljas i allokeringskostnaden för token, men om den billigaste algoritmen krävs och std::strtok svårigheter inte är överkompatibla, överväg en handspunnen lösning .

// 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);

Levande exempel

  1. std::istream_iterator använder strömmens extraktionsoperatör iterativt. Om ingången std::string är avgränsad med std::strtok kan detta expandera på alternativet std::strtok genom att eliminera dess svårigheter, tillåta inline-tokenisering och därigenom stödja genereringen av en const vector<string> , och genom att lägga till stöd för flera avgränsar vitrums-karaktär:
// 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>());

Levande exempel

  1. std::regex_token_iterator använder en std::regex att iterativt tokenisera. Det ger en mer flexibel avgränsningsdefinition. Till exempel icke-avgränsade komma-tecken och vitrum:
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() 
};

Levande exempel

Se exempel på regex_token_iterator för mer information.

Omvandling till (const) char *

För att få const char* åtkomst till data från en std::string du använda strängens c_str() . Tänk på att pekaren endast är giltig så länge som std::string är inom räckvidd och förblir oförändrad, det betyder att endast const metoder kan kallas på objektet.

C ++ 17

Funktionen data() -medlem kan användas för att få en modifierbar char* , som kan användas för att manipulera std::string data.

C ++ 11

En modifierbar char* kan också erhållas genom att ta adressen till det första tecknet: &s[0] . Inom C ++ 11 garanteras detta att ge en välformad, noll-avslutad sträng. Observera att &s[0] är välformad även om s är tomt, medan &s.front() är odefinierat om s är tomt.

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();

Hitta tecken i en sträng

För att hitta ett tecken eller en annan sträng kan du använda std::string::find . Det returnerar positionen för det första tecknet i den första matchen. Om inga matchningar hittades returnerar funktionen 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";

Hittade på plats: 21


Sökmöjligheterna utökas ytterligare med följande funktioner:

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 

Dessa funktioner kan låta dig söka efter tecken från slutet av strängen och hitta det negativa fallet (dvs. tecken som inte finns i strängen). Här är ett exempel:

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

Hittade på plats: 6

Obs: Var medveten om att funktionerna ovan inte söker efter underlag, utan snarare efter tecken i söksträngen. I detta fall hittades den sista förekomsten av 'g' på position 6 (de andra tecknen hittades inte).

Trimma tecken vid start / slut

Det här exemplet kräver rubrikerna <algorithm> , <locale> och <utility> .

C ++ 11

Att trimma en sekvens eller sträng betyder att ta bort alla ledande och efterföljande element (eller tecken) som matchar ett visst predikat. Vi trimmar först de bakre elementen, eftersom det inte innebär att några element flyttas och sedan trimas de ledande elementen. Observera att generaliseringarna nedan fungerar för alla typer av std::basic_string (t.ex. std::string och std::wstring ), och av misstag också för sekvensbehållare (t.ex. std::vector och std::list ).

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);
}

Trimning av de bakre elementen innebär att hitta det sista elementet som inte matchar predikatet och raderar därifrån:

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;
}

Att trimma de ledande elementen innebär att hitta det första elementet som inte matchar predikatet och raderar upp till det:

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;
}

För att specialisera ovanstående för att trimma whitespace i en std::string vi använda std::isspace() -funktionen som ett predikat:

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); });
}

På liknande sätt kan vi använda std::iswspace() -funktionen för std::wstring etc.

Om du vill skapa en ny sekvens som är en trimmad kopia kan du använda en separat funktion:

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

Lexikografisk jämförelse

Två std::string kan jämföras lexikografiskt med operatörerna == != , < , <= , > Och >= :

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);

Alla dessa funktioner använder den underliggande std::string::compare() -metoden för att utföra jämförelsen och returnera för booleska värden för bekvämlighet. Funktionen av dessa funktioner kan tolkas enligt följande, oavsett den faktiska implementeringen:

  • operatör == :

    Om str1.length() == str2.length() och varje teckenpar matchar, returnerar då true , annars returnerar false .

  • operatör != :

    Om str1.length() != str2.length() eller ett teckenpar inte matchar, returnerar true , annars returnerar det false .

  • operatör < eller operatör > :

    Hitta det första olika teckenparet, jämför dem sedan returnerar det booleska resultatet.

  • operatör <= eller operatör >= :

    Hitta det första olika teckenparet, jämför dem sedan returnerar det booleska resultatet.

Obs: Termen teckenpar betyder motsvarande tecken i båda strängarna med samma positioner. För bättre förståelse, om två str1 är str1 och str2 , och deras längder är n respektive m , betyder str1[i] för båda strängarna varje str1[i] och str2[i] par där i = 0, 1, 2 str2[i] .., max (n, m) . Om för något i där motsvarande tecken inte finns, det vill säga när i är större än eller lika med n eller m , skulle det betraktas som det lägsta värdet.


Här är ett exempel på att använda < :

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

assert(str2 < str1);

Stegen är följande:

  1. Jämför de första tecknen, 'B' == 'B' - gå vidare.
  2. Jämför de andra tecknen, 'a' == 'a' - gå vidare.
  3. Jämför de tredje tecknen, 'r' == 'r' - gå vidare.
  4. str2 intervallet är nu uttömt, medan str1 området fortfarande har tecken. Således str2 < str1 .

Konvertering till std :: wstring

I C ++ representeras sekvenser av tecken genom att specialisera klassen std::basic_string med en inbyggd karaktärstyp. De två stora samlingarna som definieras av standardbiblioteket är std::string och std::wstring :

  • std::string är byggd med element av typ char

  • std::wstring är byggd med element av typen wchar_t

För att konvertera mellan de två typerna, använd 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);

För att förbättra användbarheten och / eller läsbarheten kan du definiera funktioner för att utföra konverteringen:

#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);
}

Exempel på användning:

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

Det är säkert mer läsbart än std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!") .


Observera att char och wchar_t inte innebär kodning och inte anger någon storlek på byte. Till exempel wchar_t vanligtvis som en 2-bytes datatyp och innehåller typiskt UTF-16 kodad data under Windows (eller UCS-2 i versioner före Windows 2000) och som en 4-bytes datatyp kodad med UTF-32 under Linux. Detta är i kontrast till de nyare typerna char16_t och char32_t , som introducerades i C ++ 11 och garanteras vara tillräckligt stora för att innehålla ett UTF16- eller UTF32-"karaktär" (eller mer exakt, kodpunkt ).

Med hjälp av klassen std :: string_view

C ++ 17

C ++ 17 introducerar std::string_view , som helt enkelt är ett icke-ägande intervall med const char , implementerbart som antingen ett par pekare eller en pekare och en längd. Det är en överlägsen parametertyp för funktioner som kräver icke-modifierbar strängdata. Innan C ++ 17 fanns det tre alternativ för detta:

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

Alla dessa kan ersättas med:

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

Observera att std::string_view inte kan ändra underliggande data .

string_view är användbart när du vill undvika onödiga kopior.

Det erbjuder en användbar delmängd av funktionaliteten som std::string gör, även om vissa av funktionerna beter sig annorlunda:

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';

Looping genom varje karaktär

C ++ 11

std::string stöder iteratorer, och så kan du använda en avståndsbaserad slinga för att iterera igenom varje tecken:

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

Du kan använda en "traditionell" for loop för att gå igenom varje tecken:

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

Konvertering till heltal / flytande punkttyper

En std::string innehåller ett nummer kan konverteras till en heltalstyp eller en flytande punkttyp med hjälp av konverteringsfunktioner.

Observera att alla dessa funktioner slutar att analysera inmatningssträngen så snart de stöter på ett icke-numeriskt tecken, så "123abc" konverteras till 123 .


std::ato* av funktioner konverterar strängar i C-stil (teckenuppsättningar) till heltals- eller flytpunkttyper:

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());

Användning av dessa funktioner avskräcks emellertid eftersom de returnerar 0 om de inte missar strängen. Detta är dåligt eftersom 0 också kan vara ett giltigt resultat, om till exempel inmatningssträngen var "0", så det är omöjligt att avgöra om konverteringen faktiskt misslyckades.

Den nyare std::sto* -familjfunktionen konverterar std::string till heltals- eller flytpunkttyper och kastar undantag om de inte kunde analysera sina input. Du bör använda dessa funktioner om möjligt :

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);

Dessutom hanterar dessa funktioner också oktala och hexsträngar till skillnad från std::ato* . Den andra parametern är en pekare till det första okonverterade tecknet i inmatningssträngen (inte illustrerad här), och den tredje parametern är basen som ska användas. 0 är automatisk detektering av oktal (börjar med 0 ) och hex (börjar med 0x eller 0X ), och alla andra värden är basen att använda

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

Konvertering mellan teckenkodningar

Det är enkelt att konvertera mellan kodningar med C ++ 11 och de flesta kompilatorer kan hantera det på ett plattforms-sätt genom <codecvt> och <locale> rubriker.

#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;
}

Kom ihåg att Visual Studio 2015 ger stöd för dessa konverteringar men ett fel i deras biblioteksimplementering kräver att man använder en annan mall för wstring_convert när man hanterar 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());
}

Kontrollera om en sträng är ett prefix för en annan

C ++ 14

I C ++ 14 görs detta enkelt med std::mismatch som returnerar det första felparret från två områden:

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

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

Observera att en intervall-och-en-halv-version av mismatch() fanns före C ++ 14, men detta är osäkert i det fall att den andra strängen är den kortaste av de två.

C ++ 14

Vi kan fortfarande använda intervallet och en halv version av std::mismatch() , men vi måste först kontrollera att den första strängen är mest lika stor som den andra:

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

Med std::string_view kan vi skriva den direkta jämförelsen vi vill utan att behöva oroa oss för allokeringskostnader eller göra kopior:

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

Konvertering till std :: sträng

std::ostringstream kan användas för att konvertera vilken strömbar typ som helst till en strängrepresentation genom att infoga objektet i ett std::ostringstream objekt (med ströminsättningsoperatören << ) och sedan konvertera hela std::ostringstream till en std::string .

För int till exempel:

#include <sstream>

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

Att skriva din egen konverteringsfunktion, det enkla:

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

fungerar men är inte lämplig för kritisk prestandakod.

Användardefinierade klasser kan implementera ströminföringsoperatören om så önskas:

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

Bortsett från strömmar kan du sedan C ++ 11 även använda std::to_string (och std::to_wstring ) som är överbelastad för alla grundläggande typer och returnerar strängrepresentationen för dess parameter.

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow