Bagaimana cara menggabungkan string std :: dan int?


655

Saya pikir ini akan sangat sederhana tetapi menghadirkan beberapa kesulitan. Jika saya punya

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

Bagaimana cara menggabungkannya untuk mendapatkan satu string "John21"?


Herb Sutter memiliki artikel bagus tentang hal ini: "The String Formatters of Manor Farm" . Ia meliputi Boost::lexical_cast, std::stringstream, std::strstream(yang sudah ditinggalkan), dan sprintfvs snprintf.
Fred Larson

Izinkan saya menambahkan ini: Saya mencoba 'str = "hi"; str + = 5; cout << str; ' dan tidak melihat efek. Ternyata operator panggilan ini + = (char) dan menambahkan karakter yang tidak dapat dicetak.
daveagp

Jawaban:


1126

Dalam urutan abjad:

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. aman, tapi lambat; membutuhkan Peningkatan (hanya header); kebanyakan / semua platform
  2. aman, membutuhkan C ++ 11 ( to_string () sudah termasuk dalam #include <string>)
  3. aman, dan cepat; membutuhkan FastFormat , yang harus dikompilasi; kebanyakan / semua platform
  4. ( Dita )
  5. aman, dan cepat; membutuhkan pustaka {fmt} , yang bisa dikompilasi atau digunakan dalam mode hanya header; kebanyakan / semua platform
  6. aman, lambat, dan bertele-tele; membutuhkan #include <sstream>(dari standar C ++)
  7. rapuh (Anda harus menyediakan buffer yang cukup besar), cepat, dan bertele-tele; itoa () adalah ekstensi non-standar, dan tidak dijamin tersedia untuk semua platform
  8. rapuh (Anda harus menyediakan buffer yang cukup besar), cepat, dan bertele-tele; tidak memerlukan apa-apa (standar C ++); semua platform
  9. rapuh (Anda harus menyediakan buffer yang cukup besar), mungkin konversi tercepat yang mungkin , verbose; membutuhkan STLSoft (khusus header); kebanyakan / semua platform
  10. safe-ish (Anda tidak menggunakan lebih dari satu panggilan int_to_string () dalam satu pernyataan), cepat; membutuhkan STLSoft (khusus header); Khusus Windows
  11. aman, tapi lambat; membutuhkan Poco C ++ ; kebanyakan / semua platform

13
Terlepas dari satu tautan yang telah Anda terima, Anda mendasari komentar kinerja Anda?
JamieH

2
Itu hampir seluruh reputasi Anda dari satu jawaban !! Anda beruntung;) Saya pikir 8 adalah standar C (tentu saja juga C ++), tetapi mungkin layak dibedakan.
noelicus

2. lambat karena std :: to_string (umur) membuat string sementara yang ditambahkan ke hasilnya.
Igor Bukanov

Jika Anda menggunakan Arduino, Anda juga dapat menggunakan String(number).
Machado

267

Di C ++ 11, Anda dapat menggunakan std::to_string, misalnya:

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

Saya suka yang ini, sederhana. Terima kasih.
truthadjustr

85

Jika Anda memiliki Peningkatan, Anda dapat mengonversi bilangan bulat menjadi string menggunakan boost::lexical_cast<std::string>(age).

Cara lain adalah dengan menggunakan stringstreams:

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

Pendekatan ketiga adalah menggunakan sprintfatau snprintfdari perpustakaan C.

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

Poster lain disarankan untuk digunakan itoa. Ini BUKAN fungsi standar, jadi kode Anda tidak akan portabel jika Anda menggunakannya. Ada kompiler yang tidak mendukungnya.


Perhatikan bahwa snprintf tidak dijamin untuk mengakhiri string secara null. Berikut ini salah satu cara untuk memastikan itu bekerja: <pre> char buffer [128]; buffer [sizeof (buffer) -1] = '\ 0'; snprintf (buffer, sizeof (buffer) -1, "% s% d", name.c_str (), umur); std :: cout << buffer << std :: endl; </pre>
Tn. Fooz

Kecenderungan saya adalah untuk tidak pernah menggunakan sprintf, karena ini dapat mengakibatkan buffer-overflows. Contoh di atas adalah contoh yang baik di mana menggunakan sprintf tidak aman jika nama itu sangat panjang.
terson

perhatikan bahwa snprintf sama-sama non-standar c ++ (seperti itoa yang Anda sebutkan). ini diambil dari c99
Johannes Schaub - litb

@terson: Saya tidak melihat kemunculan sprintfjawaban snprintf.
David Foerster

80
#include <iostream>
#include <sstream>

std::ostringstream o;
o << name << age;
std::cout << o.str();

2
ini hebat, file header BYT adalah
sstream

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

Tanpa malu-malu dicuri dari http://www.research.att.com/~bs/bs_faq2.html .


tetapi s adalah variabel tumpukan, memori sakan bebas setelah dipanggil itos. sharus mengalokasikan dari tumpukan, dan freesetelah menggunakan, kan?
kgbook

1
kembali dengan nilai ok meskipun objek string telah keluar dari ruang lingkup, stackoverflow.com/a/3977119/5393174
kgbook

32

Ini cara termudah:

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

8
Ini adalah solusi pasca-C ++ 11!
YamHon.CHAN

23

Jika Anda memiliki C ++ 11, Anda dapat menggunakan std::to_string.

Contoh:

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

name += std::to_string(age);

std::cout << name;

Keluaran:

John21

2
Itu akan berada name += std::to_string(static_cast<long long>(age));di VC ++ 2010 seperti yang Anda lihat di sini
neonmate

@neonate Bagaimana kalau name += std::to_string(age + 0LL);bukan?
chux - Reinstate Monica

18

Sepertinya saya bahwa jawaban yang paling sederhana adalah menggunakan sprintffungsi:

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

1
snprintf bisa rumit (terutama karena berpotensi tidak dapat memasukkan karakter nol dalam situasi tertentu), tetapi saya lebih suka untuk menghindari buffer sprintf meluap masalah potensial.
terson

3
sprintf (char *, const char *, ...) akan gagal pada beberapa versi kompiler ketika Anda meneruskan std :: string ke% s. Tidak semua, meskipun (itu perilaku tidak terdefinisi) dan mungkin tergantung pada panjang string (SSO). Silakan gunakan .c_str ()
MSalters

ditambah sprintf dapat mengalami buffer overflows sehingga memungkinkan injeksi kode
Jean-François Fabre

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

11
#include <sstream>

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

Maka penggunaan Anda akan terlihat seperti ini

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

Dicari Google [dan diuji: p]


10

Masalah ini dapat dilakukan dengan banyak cara. Saya akan menunjukkannya dalam dua cara:

  1. Konversi angka menjadi string menggunakan to_string(i).

  2. Menggunakan aliran string.

    Kode:

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

Yang mana yang lebih cepat?
GyuHyeon Choi

7

Jika Anda ingin menggunakan +untuk penggabungan apa pun yang memiliki operator keluaran, Anda dapat memberikan versi templat dari operator+:

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

Kemudian Anda dapat menulis rangkaian Anda dengan mudah:

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

Keluaran:

the answer is 42

Ini bukan cara yang paling efisien, tetapi Anda tidak perlu cara yang paling efisien kecuali Anda melakukan banyak penggabungan di dalam satu lingkaran.


Jika saya mencoba menambahkan ke integer atau integer dan dobel, apakah fungsi ini akan dipanggil? Saya ingin tahu apakah solusi ini akan menggantikan penambahan yang biasa ...
Hilder Vitor Lima Pereira

Operator mengembalikan a std::string, jadi tidak akan menjadi kandidat dalam ekspresi di mana string tidak dapat dikonversi menjadi tipe yang diperlukan. Misalnya, ini operator+tidak memenuhi syarat untuk digunakan +dalam int x = 5 + 7;. Semua hal dipertimbangkan, saya tidak akan mendefinisikan operator seperti ini tanpa alasan yang sangat menarik, tetapi tujuan saya adalah untuk menawarkan jawaban yang berbeda dari yang lain.
uckelman

Anda benar (saya baru saja mengujinya ...). Dan ketika saya mencoba melakukan sesuatu seperti string s = 5 + 7 , saya mendapatkan kesalahan konversi yang tidak valid dari 'int' ke 'const char ' *
Hilder Vitor Lima Pereira

5

Jika Anda menggunakan MFC, Anda dapat menggunakan CString

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

Managed C ++ juga memiliki formatter string .


4

Std :: ostringstream adalah metode yang bagus, tetapi terkadang trik tambahan ini berguna mengubah format menjadi satu-liner:

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

Sekarang Anda dapat memformat string seperti ini:

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

4

Karena pertanyaan terkait Qt ditutup untuk pertanyaan ini, berikut ini cara melakukannya menggunakan Qt:

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

Variabel string sekarang memiliki nilai someIntVariable di tempat% 1 dan nilai someOtherIntVariable di akhir.


QString ("Sesuatu") + QString :: number (someIntVariable) juga berfungsi
gremwell

3

Ada lebih banyak opsi yang dapat digunakan untuk menggabungkan bilangan bulat (atau objek numerik lainnya) dengan string. Ini adalah 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);
}

dan Karma dari 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 mengklaim sebagai salah satu opsi tercepat untuk konversi integer ke string .



3

Anda dapat menggabungkan int ke string dengan menggunakan trik sederhana yang diberikan di bawah ini, tetapi perhatikan bahwa ini hanya berfungsi ketika integer adalah dari satu digit. Jika tidak, tambahkan angka integer demi digit ke string itu.

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

Output:  John5

2

Berikut ini adalah implementasi cara menambahkan int ke string menggunakan aspek parsing dan format dari pustaka 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
  • 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));

Yang mana yang tercepat?
GyuHyeon Choi

2

Ada fungsi yang saya tulis, yang mengambil nomor int sebagai parameter, dan mengubahnya menjadi string literal. Fungsi ini tergantung pada fungsi lain yang mengubah satu digit ke karakternya:

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

1

Dengan perpustakaan {fmt} :

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

Subset perpustakaan diusulkan untuk standardisasi sebagai P0645 Pemformatan Teks dan, jika diterima, di atas akan menjadi:

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

Penafian : Saya penulis perpustakaan {fmt}.


0

Sebagai satu liner: name += std::to_string(age);


3
Itu kode yang sama seperti pada jawaban 0x499602D2.
BDL
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.