कैसे एक एसटीडी :: स्ट्रिंग और एक इंट को अलग करना है?


655

मैंने सोचा कि यह वास्तव में सरल होगा लेकिन यह कुछ कठिनाइयों को प्रस्तुत कर रहा है। अगर मेरे पास

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

एकल स्ट्रिंग प्राप्त करने के लिए मैं उन्हें कैसे संयोजित करूं "John21"?


हर्ब सटर का इस विषय पर एक अच्छा लेख है: "द स्ट्रिंग फॉर्मेटर्स ऑफ मैनर फार्म" । वह शामिल किया गया है Boost::lexical_cast, std::stringstream, std::strstream(जो अब मान्य नहीं है), और sprintfबनाम snprintf
फ्रेड लार्सन

मुझे इसमें शामिल होने दें: मैंने 'str = "hi" आज़माया; str + = 5; cout << str? ' और कोई प्रभाव नहीं देखा। इस कॉल ऑपरेटर + = (चार) को चालू करता है और एक गैर-मुद्रण योग्य वर्ण जोड़ता है।
daveagp

जवाबों:


1125

वर्णमाला क्रम में:

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. सुरक्षित है, लेकिन धीमा है; बूस्ट की आवश्यकता है (हेडर केवल); सबसे / सभी प्लेटफार्मों
  2. सुरक्षित है, C ++ 11 ( to_string) की आवश्यकता पहले से ही इसमें शामिल है#include <string> )
  3. सुरक्षित है, और तेज़ है; FastFormat की आवश्यकता है , जिसे संकलित किया जाना चाहिए; सबसे / सभी प्लेटफार्मों
  4. ( डिट्टो )
  5. सुरक्षित है, और तेज़ है; {fmt} लाइब्रेरी की आवश्यकता है , जिसे हेडर-ओनली मोड में या तो संकलित या उपयोग किया जा सकता है; सबसे / सभी प्लेटफार्मों
  6. सुरक्षित, धीमा, और क्रिया; आवश्यकता है #include <sstream>(मानक C ++ से)
  7. भंगुर है (आपको एक बड़े बफर की आपूर्ति करनी चाहिए), तेज, और क्रिया; itoa () एक गैर-मानक एक्सटेंशन है, और सभी प्लेटफार्मों के लिए उपलब्ध होने की गारंटी नहीं है
  8. भंगुर है (आपको एक बड़े बफर की आपूर्ति करनी चाहिए), तेज, और क्रिया; कुछ भी नहीं चाहिए (मानक C ++ है); सभी प्लेटफार्मों
  9. भंगुर है (आपको एक बड़े बफर की आपूर्ति करनी चाहिए), शायद सबसे तेजी से संभव रूपांतरण , क्रिया; STLSoft की आवश्यकता है (हेडर केवल); सबसे / सभी प्लेटफार्मों
  10. safe-ish (आप एक बयान में एक से अधिक int_to_string () कॉल का उपयोग नहीं करते हैं ), तेज़; आवश्यकता है STLSoft (हेडर केवल); विंडोज केवल
  11. सुरक्षित है, लेकिन धीमा है; पोको सी ++ की आवश्यकता है ; सबसे / सभी प्लेटफार्मों

13
आपके द्वारा दिए गए एक लिंक के अलावा, आप अपने प्रदर्शन टिप्पणियों पर क्या आधार दे रहे हैं?
जेमीएच

2
यह एक उत्तर से लगभग आपकी पूरी प्रतिष्ठा है !! आप भाग्यशाली बीन;) मुझे लगता है कि 8 मानक सी है (निश्चित रूप से सी ++ भी), लेकिन शायद अंतर करने के लायक है।
noelicus

2. std के रूप में धीमा है: to_string (आयु) एक अस्थायी स्ट्रिंग बनाता है जिसे परिणाम में जोड़ा जाता है।
इगोर बुकानोव

यदि आप Arduino पर हैं, तो आप भी उपयोग कर सकते हैं String(number)
मचाडो

267

C ++ 11 में, आप उपयोग कर सकते हैं std::to_string, जैसे:

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

मुझे यह पसंद है, सरल। धन्यवाद।
truthadjustr

85

यदि आपके पास बूस्ट है, तो आप पूर्णांक को स्ट्रिंग का उपयोग करके परिवर्तित कर सकते हैं boost::lexical_cast<std::string>(age)

एक और तरीका स्ट्रिंगस्ट्रीम का उपयोग करना है:

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

एक तीसरा दृष्टिकोण सी लाइब्रेरी का उपयोग sprintfया उससे होगा snprintf

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

अन्य पोस्टरों का उपयोग करने का सुझाव दिया itoa। यह एक मानक कार्य नहीं है, इसलिए यदि आप इसका उपयोग करते हैं तो आपका कोड पोर्टेबल नहीं होगा। ऐसे कंपाइलर हैं जो इसका समर्थन नहीं करते हैं।


ध्यान दें कि स्ट्रिंग को शून्य-समाप्त करने के लिए स्निपरफ की गारंटी नहीं है। यह सुनिश्चित करने के लिए यहां एक तरीका है कि यह काम करता है: <pre> char बफर [128]; बफर [आकार (बफर) -1] = '\ 0'; स्नप्रिंट (बफर, साइज़ोफ़ (बफर) -1, "% s% d", name.c_str (), आयु); std :: cout << बफर << std :: endl; </ pre>
श्री फूज

मेरी प्रवृत्ति कभी भी स्प्रिंट का उपयोग करने की नहीं होगी, क्योंकि इससे बफर-ओवरफ्लो हो सकता है। उपरोक्त उदाहरण एक अच्छा उदाहरण है जहां स्प्रिंट का उपयोग करना असुरक्षित होगा यदि नाम बहुत लंबा था।
टर्सन

ध्यान दें कि स्निप्रफ समान रूप से गैर-मानक सी ++ है (जैसे कि जो आप उल्लेख करते हैं)। यह c99 से लिया गया है
जोहान्स

@ टेरसन: मुझे sprintfजवाब में कोई घटना नहीं दिखती है , केवल snprintf
डेविड फ़ॉस्टर 01


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

Http://www.research.att.com/~bs/bs_faq2.html से बेशर्मी से चोरी ।


लेकिन s एक स्टैक वैरिएबल है, इनवॉइस की मेमोरी sफ्री हो जाएगी itossढेर से आवंटित करना चाहिए, और freeउपयोग करने के बाद, है ना?
किग्राबुक

1
मूल्य से वापसी ठीक है, भले ही स्ट्रिंग ऑब्जेक्ट दायरे से बाहर हो गया है, stackoverflow.com/a/3977119/5393174
kgbook


23

यदि आपके पास C ++ 11 है, तो आप उपयोग कर सकते हैं std::to_string

उदाहरण:

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

name += std::to_string(age);

std::cout << name;

आउटपुट:

John21

2
यह name += std::to_string(static_cast<long long>(age));VC ++ 2010 में होगा जैसा कि आप यहां
neonmate

@neonmate name += std::to_string(age + 0LL);इसके बजाय कैसे ?
chux -

18

यह मुझे लगता है कि सबसे सरल उत्तर sprintfफ़ंक्शन का उपयोग करना है:

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

1
स्निप्रफ मुश्किल हो सकता है (मुख्य रूप से क्योंकि यह संभावित रूप से कुछ स्थितियों में अशक्त चरित्र को शामिल नहीं कर सकता है), लेकिन मुझे लगता है कि स्प्रिंटफ बफर से बचने के लिए संभावित समस्याओं से बचें।
टेरसन

3
स्प्रिंटफ (चार *, कास्ट चार * ... ...) कंपाइलर के कुछ संस्करणों पर विफल हो जाएगा जब आप एक एसटी :: स्ट्रिंग को% s पास करते हैं। सभी नहीं, हालांकि (यह अपरिभाषित व्यवहार है) और यह स्ट्रिंग की लंबाई (एसएसओ) पर निर्भर हो सकता है। कृपया उपयोग करें .c_str ()
MSalters

प्लस sprintf तो संभव कोड इंजेक्शन अतिप्रवाह बफ़र के अधीन है
जीन फ़्राँस्वा 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();
}

तब आपका उपयोग कुछ इस तरह दिखेगा

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

गुगली [और परीक्षण: पी]


10

इस समस्या को कई तरीकों से किया जा सकता है। मैं इसे दो तरह से दिखाऊंगा:

  1. संख्या का उपयोग करके स्ट्रिंग में कनवर्ट करें to_string(i)

  2. स्ट्रिंग स्ट्रीम का उपयोग करना।

    कोड:

    #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

यदि आप +किसी ऐसी चीज़ के लिए उपयोग करना चाहते हैं जिसका आउटपुट ऑपरेटर है, तो आप इसका एक टेम्प्लेट संस्करण प्रदान कर सकते हैं operator+:

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

फिर आप अपने निष्कर्षों को सीधे तरीके से लिख सकते हैं:

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

आउटपुट:

the answer is 42

यह सबसे कुशल तरीका नहीं है, लेकिन आपको सबसे कुशल तरीके की आवश्यकता नहीं है जब तक कि आप एक लूप के अंदर बहुत अधिक मात्रा में नहीं कर रहे हैं।


यदि मैं पूर्णांक या पूर्णांक और एक डबल में जोड़ने का प्रयास करता हूं, तो क्या यह फ़ंक्शन कहा जाएगा? मुझे आश्चर्य है कि अगर यह समाधान सामान्य परिवर्धन को
पार

ऑपरेटर एक रिटर्न देता है std::string, इसलिए उन अभिव्यक्तियों में उम्मीदवार नहीं होगा जहां एक स्ट्रिंग आवश्यक प्रकार में परिवर्तनीय नहीं है। उदाहरण के लिए, यह operator+उपयोग करने के लिए योग्य नहीं +है int x = 5 + 7;। सभी बातों पर विचार किया, मैं बहुत ही सम्मोहक कारण के बिना इस तरह के एक ऑपरेटर को परिभाषित नहीं करेगा , लेकिन मेरा उद्देश्य दूसरों से अलग उत्तर की पेशकश करना था।
ऑकेलमैन

आप सही हैं (मैंने अभी इसका परीक्षण किया है ...)। और जब मैंने स्ट्रिंग s = 5 + 7 जैसा कुछ करने की कोशिश की , तो मुझे 'int' से 'const char ' * में त्रुटि अमान्य रूपांतरण मिला
हिल्डर विटर लीमा परेरा


4

Std :: ostringstream एक अच्छा तरीका है, लेकिन कभी-कभी इस अतिरिक्त ट्रिक से फॉर्मेटिंग को वन-लाइनर में बदलना आसान हो सकता है:

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

अब आप तार को इस तरह से प्रारूपित कर सकते हैं:

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

4

क्यूटी से संबंधित प्रश्न को इस के पक्ष में बंद कर दिया गया था, यहां Qt का उपयोग करके इसे कैसे करें:

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

स्ट्रिंग वैरिएबल में% 1 के स्थान पर कुछIVVViable का मूल्य और अंत में कुछOtherIntVariable का मान है।


QString ("कुछ") + QString :: संख्या (someIntVariable) भी काम करती है
gremwell

3

स्ट्रिंग के साथ पूर्णांक (या अन्य संख्यात्मक वस्तु) का उपयोग करने के लिए अधिक विकल्प संभव हैं। यह 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);
}

और 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 कर्म स्ट्रिंग रूपांतरण के लिए पूर्णांक के लिए सबसे तेज विकल्प में से एक होने का दावा करता है ।



3

आप नीचे दिए गए सरल ट्रिक का उपयोग करके स्ट्रिंग को intatenate कर सकते हैं, लेकिन ध्यान दें कि यह तभी काम करता है जब पूर्णांक एकल अंक का हो। अन्यथा, उस स्ट्रिंग को अंक द्वारा पूर्णांक अंक जोड़ें।

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

Output:  John5

2

यहाँ 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));
  • बढ़ावा :: lexical_cast
#include <boost/lexical_cast.hpp>

std::string query("John " + boost::lexical_cast<std::string>(age));

सबसे तेज कौन सा है?
गयुयोन चोई

2

एक फ़ंक्शन है जो मैंने लिखा था, जो इंटिमेट नंबर को पैरामीटर के रूप में लेता है, और इसे एक स्ट्रिंग शाब्दिक में परिवर्तित करता है। यह फ़ंक्शन किसी अन्य फ़ंक्शन पर निर्भर है जो किसी एकल अंक को उसके चार समतुल्य में परिवर्तित करता है:

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

साथ {} fmt पुस्तकालय :

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

पुस्तकालय का एक सबसेट P0645 पाठ प्रारूपण के रूप में मानकीकरण के लिए प्रस्तावित है और, यदि स्वीकार किया जाता है, तो उपरोक्त बन जाएगा:

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

अस्वीकरण : मैं {fmt} पुस्तकालय का लेखक हूं।


0

एक लाइनर के रूप में: name += std::to_string(age);


3
यह वही कोड है जो 0x499602D2 उत्तर में है।
बीडीएल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.