web-dev-qa-db-fra.com

Comment concaténer un std :: string et un int?

Je pensais que ce serait très simple mais cela pose quelques difficultés. Si j'ai

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

Comment les combiner pour obtenir une seule chaîne "John21"?

612
Obediah Stane

Par ordre alphabétique:

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. est sûr, mais lent; requiert Boost (en-tête uniquement); la plupart/toutes les plateformes
  2. est sûr, nécessite C++ 11 ( to_string () est déjà inclus dans #include <string>)
  3. est sûr et rapide; requiert FastFormat , qui doit être compilé; la plupart/toutes les plateformes
  4. est sûr et rapide; requiert FastFormat , qui doit être compilé; la plupart/toutes les plateformes
  5. est sûr et rapide; requiert la bibliothèque {fmt} , qui peut être compilé ou utilisé dans un mode en-tête uniquement; la plupart/toutes les plateformes
  6. sûr, lent et prolixe; nécessite #include <sstream> (à partir de C++ standard)
  7. est fragile (vous devez fournir un tampon suffisamment grand), rapide et prolixe; itoa () est une extension non standard, et il n'est pas garanti qu'elle soit disponible pour toutes les plateformes.
  8. est fragile (vous devez fournir un tampon suffisamment grand), rapide et prolixe; ne nécessite rien (est standard C++); toutes les plateformes
  9. est fragile (vous devez fournir une mémoire tampon suffisamment grande), probablement la conversion la plus rapide possible , verbose; requiert STLSoft (en-tête uniquement); la plupart/toutes les plateformes
  10. safe-ish (vous n'utilisez pas plus d'un int_to_string () appel dans une seule instruction), fast; requiert STLSoft (en-tête uniquement); Windows uniquement
  11. est sûr, mais lent; requiert Poco C++ ; la plupart/toutes les plateformes
1039
DannyT

En C++ 11, vous pouvez utiliser std::to_string, par exemple:

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

Si vous avez Boost, vous pouvez convertir l'entier en chaîne en utilisant boost::lexical_cast<std::string>(age).

Une autre façon consiste à utiliser des flux de chaîne:

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

Une troisième approche consisterait à utiliser sprintf ou snprintf de la bibliothèque C.

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

D'autres affiches ont suggéré d'utiliser itoa. Ce n'est PAS une fonction standard, votre code ne sera donc pas portable si vous l'utilisez. Il y a des compilateurs qui ne le supportent pas.

81
Jay Conrod
#include <iostream>
#include <sstream>

std::ostringstream o;
o << name << age;
std::cout << o.str();
73
Ben Hoffstein
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string itos(int i) // convert int to string
{
    stringstream s;
    s << i;
    return s.str();
}

Volé sans vergogne à http://www.research.att.com/~bs/bs_faq2.html .

50
tloach

C'est le moyen le plus simple:

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

Si vous avez C++ 11, vous pouvez utiliser std::to_string.

Exemple:

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

name += std::to_string(age);

std::cout << name;

Sortie:

John21
22
0x499602D2

Il me semble que la réponse la plus simple consiste à utiliser la fonction sprintf:

sprintf(outString,"%s%d",name,age);
18
user12576
#include <string>
#include <sstream>
using namespace std;
string concatenate(std::string const& name, int i)
{
    stringstream s;
    s << name << i;
    return s.str();
}
15
Seb Rose

Herb Sutter a un bon article sur ce sujet: "Les formateurs de chaîne de Manor Farm" . Il couvre Boost::lexical_cast, std::stringstream, std::strstream (qui est obsolète) et sprintf vs snprintf.

12
Fred Larson
#include <sstream>

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

Ensuite, votre utilisation ressemblerait à quelque chose comme ça

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

googlé [et testé: p]

11
Zing-

Si vous souhaitez utiliser + pour la concaténation de tout ce qui a un opérateur de sortie, vous pouvez fournir une version modèle de operator+:

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

Ensuite, vous pouvez écrire vos concaténations de manière simple:

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

Sortie:

the answer is 42

Ce n'est pas le moyen le plus efficace, mais vous n'avez pas besoin du moyen le plus efficace à moins de faire beaucoup de concaténation dans une boucle.

7
uckelman

Ce problème peut être résolu de plusieurs manières. Je vais le montrer de deux manières:

  1. Convertissez le nombre en chaîne à l'aide de to_string(i).

  2. Utilisation de flux de chaîne.

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

Si vous utilisez MFC, vous pouvez utiliser un CString

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

C++ géré a également un formateur de chaîne .

5
bsruth

Std :: ostringstream est une bonne méthode, mais parfois, cette astuce supplémentaire peut s'avérer utile pour transformer le formatage en une ligne:

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

Vous pouvez maintenant formater des chaînes comme ceci:

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

Comme une question liée à Qt a été fermée en faveur de celle-ci, voici comment procéder en utilisant Qt:

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

La variable chaîne a maintenant la valeur de someIntVariable à la place de% 1 et celle de someOtherIntVariable à la fin.

4
leinir

Réponse commune: itoa ()

C'est mauvais. itoa n'est pas standard, comme indiqué ici .

3
Tom Ritter

Il y a plus d'options possibles à utiliser pour concaténer un entier (ou un autre objet numérique) avec une chaîne. C'est 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);
}

et Karma de 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 prétend être l’un des option la plus rapide pour convertir un entier en chaîne .

3
mloskot

Si vous voulez obtenir un caractère * et que vous avez utilisé stringstream conformément à ce que les répondants ci-dessus ont décrit, faites par exemple:

myFuncWhichTakesPtrToChar(ss.str().c_str());

Puisque stringstream retourne via str () est une chaîne standard, vous pouvez alors appeler c_str () pour obtenir le type de sortie souhaité.

3
Engineer

Vous pouvez concaténer int en chaîne en utilisant l'astuce simple donnée ci-dessous, mais notez que cela ne fonctionne que lorsque l'entier est un chiffre. Sinon, ajoutez un nombre entier chiffre par chiffre à cette chaîne.

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

Output:  John5
2
Sukhbir

Voici une implémentation expliquant comment ajouter un int à une chaîne à l'aide des facettes d'analyse et de formatage de la bibliothèque IOStreams.

#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
}
2
0x499602D2

J'ai écrit une fonction qui prend le nombre entier en tant que paramètre et le convertit en un littéral de chaîne. Cette fonction dépend d'une autre fonction qui convertit un seul chiffre en son équivalent en caractères:

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;
}
2
Reda Lahdili
  • 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));
2
Isma Rekathakusuma

Avec la {fmt} library :

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

Un sous-ensemble de la bibliothèque est proposé pour normalisation sous la forme P0645 Mise en forme du texte et, si cette option est acceptée, celle-ci devient:

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

Disclaimer : Je suis l'auteur de la bibliothèque {fmt}.

1
vitaut

Le réponse détaillée est enfoui sous d'autres réponses et en refait partie:

#include <iostream> // cout
#include <string> // string, to_string(some_number_here)

using namespace std;

int main() {
    // using constants
    cout << "John" + std::to_string(21) << endl;
    // output is:
    //    John21

    // using variables
    string name = "John";
    int age = 21;
    cout << name + to_string(age) << endl;
    // output is:
    //    John21
}
1
Manohar Reddy Poreddy