Hoe een STD :: string en een int

Ik dacht dat dit heel eenvoudig zou zijn, maar het presenteert wat moeilijkheden. Als ik

heb

std::string name = "John";
int age = 21;

Hoe combineer ik ze om een ​​enkele string "John21"te krijgen?


Antwoord 1, Autoriteit 100%

In alfabetische volgorde:

std::string name = "John";
int age = 21;
std::string result;
// 1. with Boost
result = name + boost::lexical_cast<std::string>(age);
// 2. with C++11
result = name + std::to_string(age);
// 3. with FastFormat.Format
fastformat::fmt(result, "{0}{1}", name, age);
// 4. with FastFormat.Write
fastformat::write(result, name, age);
// 5. with the {fmt} library
result = fmt::format("{}{}", name, age);
// 6. with IOStreams
std::stringstream sstm;
sstm << name << age;
result = sstm.str();
// 7. with itoa
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + itoa(age, numstr, 10);
// 8. with sprintf
char numstr[21]; // enough to hold all numbers up to 64-bits
sprintf(numstr, "%d", age);
result = name + numstr;
// 9. with STLSoft's integer_to_string
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + stlsoft::integer_to_string(numstr, 21, age);
// 10. with STLSoft's winstl::int_to_string()
result = name + winstl::int_to_string(age);
// 11. With Poco NumberFormatter
result = name + Poco::NumberFormatter().format(age);
  1. is veilig, maar langzaam; vereist boost (alleen header); De meeste / alle platforms
  2. is veilig, vereist C++ 11 (to_string () is al inbegrepen in #include <string>)
  3. is veilig en snel; Vereist fastformat , die moeten worden gecompileerd; De meeste / alle platforms
  4. (Ditto )
  5. is veilig en snel; vereist de {FMT} -bibliotheek , die ofwel kan worden gecompileerd of gebruikt in een modus header-only; De meeste / alle platforms
  6. veilig, traag en verbod; vereist #include <sstream>(van standaard C++)
  7. is bros (u moet een grote genoeg buffer leveren), snel en verbod; ITOA () is een niet-standaardextensie en is niet gegarandeerd beschikbaar voor alle platforms
  8. is bros (u moet een grote genoeg buffer leveren), snel en verbod; vereist niets (is standaard C++); Alle platforms
  9. is bros (u moet een grote genoeg buffer leveren), waarschijnlijk de snelst mogelijke conversie , uitgebreid; vereist stlsoft (alleen header-alleen); De meeste / alle platforms
  10. Safe-ish (u gebruikt niet meer dan één int_to_string () oproep in een enkele verklaring), snel; vereist stlsoft (alleen header-alleen); Alleen Windows
  11. is veilig, maar langzaam; vereist POCO C++ ; De meeste / alle platforms

Antwoord 2, Autoriteit 24%

In C++ 11 kunt u std::to_string, b.v.:

auto result = name + std::to_string( age );

Antwoord 3, autoriteit 7%

Als je Boost hebt, kun je het gehele getal converteren naar een string met boost::lexical_cast<std::string>(age).

Een andere manier is om stringstreams te gebruiken:

std::stringstream ss;
ss << age;
std::cout << name << ss.str() << std::endl;

Een derde benadering zou zijn om sprintfof snprintfuit de C-bibliotheek te gebruiken.

char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d", name.c_str(), age);
std::cout << buffer << std::endl;

Andere posters stelden voor om itoate gebruiken. Dit is GEEN standaardfunctie, dus uw code is niet overdraagbaar als u deze gebruikt. Er zijn compilers die dit niet ondersteunen.


Antwoord 4, autoriteit 7%

#include <iostream>
#include <sstream>
std::ostringstream o;
o << name << age;
std::cout << o.str();

Antwoord 5, autoriteit 5%

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string itos(int i) // convert int to string
{
    stringstream s;
    s << i;
    return s.str();
}

Schandalig gestolen van http://www.research.att.com/~bs /bs_faq2.html.


Antwoord 6, autoriteit 3%

Dit is de gemakkelijkste manier:

string s = name + std::to_string(age);

Antwoord 7, autoriteit 2%

Als je C++11 hebt, kun je std::to_stringgebruiken.

Voorbeeld:

std::string name = "John";
int age = 21;
name += std::to_string(age);
std::cout << name;

Uitvoer:

John21

Antwoord 8

Het lijkt mij dat het eenvoudigste antwoord is om de functie sprintfte gebruiken:

sprintf(outString,"%s%d",name,age);

Antwoord 9

#include <string>
#include <sstream>
using namespace std;
string concatenate(std::string const& name, int i)
{
    stringstream s;
    s << name << i;
    return s.str();
}

Antwoord 10

#include <sstream>
template <class T>
inline std::string to_string (const T& t)
{
   std::stringstream ss;
   ss << t;
   return ss.str();
}

Dan zou je verbruik er ongeveer zo uit zien

  std::string szName = "John";
   int numAge = 23;
   szName += to_string<int>(numAge);
   cout << szName << endl;

Googled[en getest: p ]


Antwoord 11

Dit probleem kan op veel manieren worden opgelost. Ik zal het op twee manieren laten zien:

  1. Converteer het getal naar string met to_string(i).

  2. Tekenreeksstreams gebruiken.

    Code:

    #include <string>
    #include <sstream>
    #include <bits/stdc++.h>
    #include <iostream>
    using namespace std;
    int main() {
        string name = "John";
        int age = 21;
        string answer1 = "";
        // Method 1). string s1 = to_string(age).
        string s1=to_string(age); // Know the integer get converted into string
        // where as we know that concatenation can easily be done using '+' in C++
        answer1 = name + s1;
        cout << answer1 << endl;
        // Method 2). Using string streams
        ostringstream s2;
        s2 << age;
        string s3 = s2.str(); // The str() function will convert a number into a string
        string answer2 = "";  // For concatenation of strings.
        answer2 = name + s3;
        cout << answer2 << endl;
        return 0;
    }
    

Antwoord 12

In C++ 20 kunt u doen:

auto result = std::format("{}{}", name, age);

In de tussentijd kunt u de {FMT} -bibliotheek , std::formatis gebaseerd op:

auto result = fmt::format("{}{}", name, age);

Disclaimer : Ik ben de auteur van de bibliotheek {FMT} en C++ 20 std::format.


Antwoord 13

Als u +wilt gebruiken voor aaneenbonnen van alles wat een uitvoeroperator heeft, kunt u een sjabloonversie van operator+:

template <typename L, typename R> std::string operator+(L left, R right) {
  std::ostringstream os;
  os << left << right;
  return os.str();
}

Dan kunt u uw aaneenschakelingen op een eenvoudige manier schrijven:

std::string foo("the answer is ");
int i = 42;
std::string bar(foo + i);    
std::cout << bar << std::endl;

Uitvoer:

the answer is 42

Dit is niet de meest efficiënte manier, maar je hebt niet de meest efficiënte manier nodig, tenzij je veel aaneenschakeling binnen een lus doet.


Antwoord 14

Als u MFC gebruikt, kunt u een CString gebruiken

CString nameAge = "";
nameAge.Format("%s%d", "John", 21);

Managed C++ heeft ook een
tekenreeksopmaak.


Antwoord 15

De std::ostringstream is een goede methode, maar soms kan deze extra truc handig zijn om de opmaak om te zetten in een one-liner:

#include <sstream>
#define MAKE_STRING(tokens) /****************/ \
    static_cast<std::ostringstream&>(          \
        std::ostringstream().flush() << tokens \
    ).str()                                    \
    /**/

Je kunt strings nu als volgt opmaken:

int main() {
    int i = 123;
    std::string message = MAKE_STRING("i = " << i);
    std::cout << message << std::endl; // prints: "i = 123"
}

Antwoord 16

Omdat een Qt-gerelateerde vraag werd gesloten ten gunste van deze, kun je dit als volgt doen met Qt:

QString string = QString("Some string %1 with an int somewhere").arg(someIntVariable);
string.append(someOtherIntVariable);

De stringvariabele heeft nu de waarde van someIntVariable in plaats van %1 en de waarde van someOtherIntVariable aan het einde.


Antwoord 17

Er zijn meer opties mogelijk om integer (of ander numeriek object) samen te voegen met string. Het is Boost.Format

#include <boost/format.hpp>
#include <string>
int main()
{
    using boost::format;
    int age = 22;
    std::string str_age = str(format("age is %1%") % age);
}

en Karma van Boost.Spirit(v2)

#include <boost/spirit/include/karma.hpp>
#include <iterator>
#include <string>
int main()
{
    using namespace boost::spirit;
    int age = 22;
    std::string str_age("age is ");
    std::back_insert_iterator<std::string> sink(str_age);
    karma::generate(sink, int_, age);
    return 0;
}

Boost.Spirit Karma beweert een van de snelste optie voor conversie van integer naar string.


Antwoord 18

Als oneliner: name += std::to_string(age);


Antwoord 19

Hier is een implementatie van hoe je een int toevoegt aan een string met behulp van de facetten voor parseren en formatteren uit de IOStreams-bibliotheek.

#include <iostream>
#include <locale>
#include <string>
template <class Facet>
struct erasable_facet : Facet
{
    erasable_facet() : Facet(1) { }
    ~erasable_facet() { }
};
void append_int(std::string& s, int n)
{
    erasable_facet<std::num_put<char,
                                std::back_insert_iterator<std::string>>> facet;
    std::ios str(nullptr);
    facet.put(std::back_inserter(s), str,
                                     str.fill(), static_cast<unsigned long>(n));
}
int main()
{
    std::string str = "ID: ";
    int id = 123;
    append_int(str, id);
    std::cout << str; // ID: 123
}

Antwoord 20

Algemeen antwoord: itoa()

Dit is slecht. itoais niet-standaard, zoals aangegeven hier.


Antwoord 21

  • std::ostringstream
#include <sstream>
std::ostringstream s;
s << "John " << age;
std::string query(s.str());
  • std::to_string (C++11)
std::string query("John " + std::to_string(age));
  • boost::lexical_cast
#include <boost/lexical_cast.hpp>
std::string query("John " + boost::lexical_cast<std::string>(age));

Antwoord 22

Je kunt int samenvoegen met string door de onderstaande eenvoudige truc te gebruiken, maar merk op dat dit alleen werkt als integer uit één cijfer bestaat. Voeg anders een geheel getal cijfer voor cijfer toe aan die tekenreeks.

string name = "John";
int age = 5;
char temp = 5 + '0';
name = name + temp;
cout << name << endl;
Output:  John5

Antwoord 23

Er is een functie die ik heb geschreven, die het int-nummer als parameter neemt en deze naar een letterlijke tekenreeks converteert. Deze functie is afhankelijk van een andere functie die een enkel cijfer omzet in zijn char-equivalent:

char intToChar(int num)
{
    if (num < 10 && num >= 0)
    {
        return num + 48;
        //48 is the number that we add to an integer number to have its character equivalent (see the unsigned ASCII table)
    }
    else
    {
        return '*';
    }
}
string intToString(int num)
{
    int digits = 0, process, single;
    string numString;
    process = num;
    // The following process the number of digits in num
    while (process != 0)
    {
        single  = process % 10; // 'single' now holds the rightmost portion of the int
        process = (process - single)/10;
        // Take out the rightmost number of the int (it's a zero in this portion of the int), then divide it by 10
        // The above combination eliminates the rightmost portion of the int
        digits ++;
    }
    process = num;
    // Fill the numString with '*' times digits
    for (int i = 0; i < digits; i++)
    {
        numString += '*';
    }
    for (int i = digits-1; i >= 0; i--)
    {
        single = process % 10;
        numString[i] = intToChar ( single);
        process = (process - single) / 10;
    }
    return numString;
}

Antwoord 24

In C++ 20 kun je een variadische lambda hebben die willekeurige streambare typen in een paar regels aaneenvoegt tot een string:

auto make_string=[os=std::ostringstream{}](auto&& ...p) mutable 
{ 
  (os << ... << std::forward<decltype(p)>(p) ); 
  return std::move(os).str();
};
int main() {
std::cout << make_string("Hello world: ",4,2, " is ", 42.0);
}

zie https://godbolt.org/z/dEe9h75eb

het gebruik van move(os).str() garandeert dat de stringbuffer van het ostringstream-object leeg is de volgende keer dat de lambda wordt aangeroepen.

Other episodes