C ++ में नंबर को स्ट्रिंग और इसके विपरीत में कैसे कन्वर्ट करें


120

चूंकि यह सवाल हर हफ्ते के बारे में पूछा जाता है, इसलिए यह अक्सर पूछे जाने वाले प्रश्न उपयोगकर्ताओं की बहुत मदद कर सकते हैं।

  • C ++ में एक पूर्णांक को स्ट्रिंग में कैसे बदलें

  • स्ट्रिंग को C ++ में पूर्णांक में कैसे परिवर्तित करें

  • C ++ में फ़्लोटिंग-पॉइंट संख्या को स्ट्रिंग में कैसे परिवर्तित किया जाए

  • C ++ में फ्लोटिंग-पॉइंट नंबर पर स्ट्रिंग कैसे कन्वर्ट करें


इस तरह के रूपांतरण के लिए, मेरे पास एक बुकमार्क converttypes.com है
फिरोजोक नदीम

जवाबों:


129

C ++ 11 के लिए अद्यतन

C++11मानक के रूप में , स्ट्रिंग-टू-नंबर रूपांतरण और इसके विपरीत मानक पुस्तकालय में निर्मित होते हैं। निम्नलिखित सभी कार्य <string>(पैराग्राफ 21.5 के अनुसार) मौजूद हैं।

स्ट्रिंग टू न्यूमेरिक

float              stof(const string& str, size_t *idx = 0);
double             stod(const string& str, size_t *idx = 0);
long double        stold(const string& str, size_t *idx = 0);
int                stoi(const string& str, size_t *idx = 0, int base = 10);
long               stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long      stoul(const string& str, size_t *idx = 0, int base = 10);
long long          stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

इनमें से प्रत्येक इनपुट के रूप में एक स्ट्रिंग लेते हैं और इसे एक संख्या में बदलने की कोशिश करेंगे। यदि कोई मान्य संख्या का निर्माण नहीं किया जा सकता है, उदाहरण के लिए क्योंकि कोई संख्यात्मक डेटा नहीं है या संख्या प्रकार के लिए आउट-ऑफ-रेंज है, तो एक अपवाद फेंक दिया जाता है ( std::invalid_argumentया std::out_of_range)।

यदि रूपांतरण सफल हुआ और idxनहीं 0,idx तो पहले वर्ण का सूचकांक होगा जिसमें डिकोडिंग के लिए उपयोग नहीं किया गया था। यह अंतिम चरित्र के पीछे एक सूचकांक हो सकता है।

अंत में, अभिन्न प्रकार 9 से बड़े अंकों के लिए एक आधार निर्दिष्ट करने की अनुमति देते हैं, वर्णमाला ग्रहण की जाती है ( a=10जब तक z=35)। आप फ़्लोटिंग-पॉइंट नंबरों , हस्ताक्षरित पूर्णांक और अहस्ताक्षरित पूर्णांक के लिए यहां सटीक स्वरूपण के बारे में अधिक जानकारी प्राप्त कर सकते हैं

अंत में, प्रत्येक फ़ंक्शन के लिए एक अधिभार भी है जो std::wstringपहले पैरामीटर के रूप में स्वीकार करता है ।

स्ट्रिंग के लिए संख्यात्मक

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

ये अधिक सीधे हैं, आप उपयुक्त संख्यात्मक प्रकार पास करते हैं और आपको एक स्ट्रिंग वापस मिलती है। स्वरूपण विकल्पों के लिए आपको C ++ 03 स्ट्रिंग विकल्प पर वापस जाना चाहिए और स्ट्रीम मैनिपुलेटर्स का उपयोग करना चाहिए, जैसा कि यहां एक अन्य उत्तर में बताया गया है।

जैसा कि टिप्पणियों में उल्लेख किया गया है कि ये फ़ंक्शन एक डिफ़ॉल्ट मंटिसा परिशुद्धता पर वापस आते हैं जो संभवतः अधिकतम परिशुद्धता नहीं है। यदि आपके आवेदन के लिए अधिक सटीकता की आवश्यकता है, तो अन्य स्ट्रिंग प्रारूपण प्रक्रियाओं पर वापस जाना सबसे अच्छा है।

वहाँ भी इसी तरह के कार्यों को परिभाषित किया जाता है जिन्हें नाम दिया गया है to_wstring, ये वापस आ जाएंगे std::wstring


3
std::to_stringफ्लोटिंग पॉइंट प्रकारों के लिए बहुत सटीक खो देता है। उदाहरण के लिए double f = 23.4323897462387526; std::string f_str = std::to_string(f);, 23.432390 का एक स्ट्रिंग देता है। यह इन फ़ंक्शंस का उपयोग करके ट्रिप फ़्लोटिंग पॉइंट मानों को गोल करना असंभव बनाता है।
fun4jimmy

@ fun4jimmy यह मानक या कार्यान्वयन विशिष्ट द्वारा लगाया गया प्रतिबंध है? इसे उत्तर में जोड़ देंगे। ऐसा नहीं है कि स्ट्रिंग्स के माध्यम से गोल-ट्रिपिंग फ्लोट्स एक अच्छा विचार है।
किलियनडीएस 7

सी ++ मानक कहते हैं, " यह दिखाता है: प्रत्येक समारोह एक स्ट्रिंग उद्देश्य यह है कि फोन करके उत्पन्न होगा अपने तर्क के मूल्य का चरित्र प्रतिनिधित्व पकड़े रिटर्न sprintf(buf, fmt, val)का एक फॉर्मेट स्पेसिफायर साथ "% d " , "% u " , "% ld " , " % lu " , "% lld " , "% llu " , "% f " , "% f " , या "% Lf " , क्रमशः, जहां bufपर्याप्त आकार का आंतरिक वर्ण बफर नामित करता है। "मैं पर एक नज़र था C99 के लिए मानक printf और मुझे लगता है कि दशमलव स्थानों की संख्या पर निर्भर है#define DECIMAL_DIG हैतैरना
fun4jimmy

ब्रूस डॉसन के पास कुछ अच्छे लेख हैं कि उनके ब्लॉग पर राउंड ट्रिपिंग फ्लो पॉइंट संख्याओं के लिए क्या आवश्यक है ।
fun4jimmy

2
ये सभी कार्य वैश्विक लोकेल से प्रभावित होते हैं, जिससे यदि आप पुस्तकालयों का उपयोग करते हैं, और विशेष रूप से थ्रेड्स का उपयोग करते हुए समस्या हो सकती है। : मेरे सवाल का यहाँ देखें stackoverflow.com/questions/31977457/...
अध्यक्ष

86

C ++ 03 में एक संख्या को स्ट्रिंग में कैसे परिवर्तित करें

  1. का प्रयोग न करेंitoa याitofकार्यों क्योंकि वे गैर मानक और इसलिए पोर्टेबल नहीं हैं।
  2. स्ट्रिंग स्ट्रीम का उपयोग करें

     #include <sstream>  //include this to use string streams
     #include <string> 
    
    int main()
    {    
        int number = 1234;
    
        std::ostringstream ostr; //output string stream
        ostr << number; //use the string stream just like cout,
        //except the stream prints not to stdout but to a string.
    
        std::string theNumberString = ostr.str(); //the str() function of the stream 
        //returns the string.
    
        //now  theNumberString is "1234"  
    }

    ध्यान दें कि आप स्ट्रिंग स्ट्रीम का उपयोग फ्लोटिंग-पॉइंट नंबरों को स्ट्रिंग में बदलने के लिए भी कर सकते हैं, और जैसे चाहें वैसे स्ट्रिंग को फॉर्मेट करने के लिए भी cout

    std::ostringstream ostr;
    float f = 1.2;
    int i = 3;
    ostr << f << " + " i << " = " << f + i;   
    std::string s = ostr.str();
    //now s is "1.2 + 3 = 4.2" 

    आप इस तरह के रूप में धारा manipulators, उपयोग कर सकते हैं std::endl, std::hexऔर कार्यों std::setw(), std::setprecision()बिल्कुल के साथ के रूप में एक ही तरीके से आदि स्ट्रिंग धाराओं के साथcout

    के std::ostringstream साथ भ्रमित मत करोstd::ostrstream । बाद वाला पदावनत है

  3. बूस्ट लेक्सिकल कास्ट का उपयोग करें । यदि आप बूस्ट से परिचित नहीं हैं, तो इस lexical_cast जैसी छोटी लाइब्रेरी से शुरुआत करना एक अच्छा विचार है। बूस्ट डाउनलोड करने और इंस्टॉल करने और इसके प्रलेखन के लिए यहां जाएं । हालांकि बढ़ावा C ++ मानक में नहीं है, लेकिन बढ़ावा देने के कई पुस्तकालयों को अंततः मानकीकृत किया जाता है और बढ़ावा को व्यापक रूप से सबसे अच्छा C ++ पुस्तकालयों के रूप में माना जाता है।

    लेक्सिकल कास्ट नीचे की धाराओं का उपयोग करता है, इसलिए मूल रूप से यह विकल्प पिछले वाले के समान है, बस कम क्रिया।

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       float f = 1.2;
       int i = 42;
       std::string sf = boost::lexical_cast<std::string>(f); //sf is "1.2"
       std::string si = boost::lexical_cast<std::string>(i); //sf is "42"
    }

C ++ 03 में एक स्ट्रिंग को संख्या में कैसे परिवर्तित करें

  1. सी से विरासत में मिला सबसे हल्का विकल्प, फ़ंक्शंस atoi(पूर्णांक के लिए पूर्णांक) और atof(फ़्लोटिंग-पॉइंट वैल्यूज़ के लिए (वर्णमाला फ़्लोट करने के लिए)) है। ये फ़ंक्शन सी-स्टाइल स्ट्रिंग को एक तर्क के रूप में लेते हैं ( const char *) और इसलिए उनके उपयोग को एक अच्छा सी ++ अभ्यास नहीं माना जा सकता है। cplusplus.com के पास atoi और atof दोनों पर आसानी से समझने वाले डॉक्यूमेंट हैं जिनमें खराब इनपुट के मामले में वे कैसे व्यवहार करते हैं। हालाँकि लिंक में एक त्रुटि है जो मानक के अनुसार यदि इनपुट संख्या लक्ष्य प्रकार में फिट होने के लिए बहुत बड़ी है, तो व्यवहार अनिर्धारित है।

    #include <cstdlib> //the standard C library header
    #include <string>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //the c_str() function "converts" 
        double f = atof(sf.c_str()); //std::string to const char*
    }
  2. स्ट्रिंग स्ट्रीम (इस समय इनपुट स्ट्रिंग स्ट्रीम istringstream) का उपयोग करें। फिर से, istringstream का उपयोग उसी तरह किया जाता है cin। फिर, istringstreamसाथ भ्रमित मत करो istrstream। बाद वाला पदावनत है।

    #include <sstream>
    #include <string>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream istr(inputString);
       int i1, i2;
       float f;
       istr >> i1 >> f >> i2;
       //i1 is 1234, f is 12.3, i2 is 44  
    }
  3. बूस्ट लेक्सिकल कास्ट का उपयोग करें ।

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       float f = boost::lexical_cast<float>(sf); //f is 42.2
       int i = boost::lexical_cast<int>(si);  //i is 42
    }       

    खराब इनपुट के मामले में, lexical_castअपवाद का प्रकार फेंकता हैboost::bad_lexical_cast


4
इसके लिए atoiउत्कृष्ट अधिशेष प्रलेखन उत्कृष्ट नहीं है, यह गलत है। यह उल्लेख करने में विफल रहता है कि यदि स्ट्रिंग के संख्यात्मक मान का प्रतिनिधित्व नहीं किया जा सकता है int, तो व्यवहार अपरिभाषित है। इसके बजाय यह कहता है कि आउट-ऑफ-रेंज मान INT_MAX/ से जुड़े हुए हैं INT_MIN, जो मुझे C ++ 03 या C89 में नहीं मिलेंगे। अविश्वासित / असत्यापित इनपुट के लिए, या जब आधारों में काम करने वाली धाराएँ समर्थन नहीं करती हैं, तो आपको जरूरत है strtol, जिसने त्रुटि व्यवहार को परिभाषित किया है। और के लिए इसी तरह की टिप्पणी atof/ strtod
स्टीव जेसोप

2
cplusplus.com "atoi" के बारे में गलत है। यह रिटर्न वैल्यू के बारे में कहता है "यदि कोई वैध रूपांतरण नहीं किया जा सकता है, तो एक शून्य मान लौटाया जाता है। यदि सही मान प्रतिनिधित्व योग्य मानों की सीमा से बाहर है, तो INT_MAX या INT_MIN वापस कर दिया जाता है।", लेकिन कल्पना कहती है कि "यदि। परिणाम के मूल्य का प्रतिनिधित्व नहीं किया जा सकता है, व्यवहार fi ned है। और यह कि "त्रुटि पर व्यवहार को छोड़कर, वे इसके बराबर हैं (int)strtol(nptr, (char **)NULL, 10)। अटोई [...] फ़ंक्शन परिवर्तित मान लौटाते हैं।" cplusplus.com को शुरुआती लोगों के लिए जानकारी का अविश्वसनीय स्रोत माना जाता है।
जोहान्स शाउब - १५:०५ पर

istr >> i1 >> f >> i2;बुरी तरह से सफलता के लिए एक जाँच याद आती है।
sbi

4
जोड़ सकते हैंstd::to_string
Pubby

1
@ArmenTsirunyan: +10 मेरे अंत से, एक सबसे अच्छा जवाब जो मैंने कभी देखा है वह भी गहराई से। आपके उत्तर के लिए धन्यवाद।
अभिनीत

4

C ++ 17 में, नए फ़ंक्शंस std :: to_chars और std :: from_chars को हेडर charconv में पेश किया जाता है

std :: to_chars स्थानीय-स्वतंत्र, गैर-आवंटन, और गैर-फेंकना है।

अन्य पुस्तकालयों (जैसे std :: sprintf) द्वारा उपयोग की जाने वाली स्वरूपण नीतियों का केवल एक छोटा सा उप-समूह प्रदान किया गया है।

से std :: to_chars , के लिए एक ही std :: from_chars

गारंटी है कि std :: from_chars, the_chars द्वारा फॉर्मेट की गई प्रत्येक फ़्लोटिंग-पॉइंट वैल्यू को ठीक कर सकता है, केवल तभी प्रदान किया जाता है जब दोनों फ़ंक्शन समान कार्यान्वयन से हों

 // See en.cppreference.com for more information, including format control.
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <charconv>

using Type =  /* Any fundamental type */ ;
std::size_t buffer_size = /* ... */ ;

[[noreturn]] void report_and_exit(int ret, const char *output) noexcept 
{
    std::printf("%s\n", output);
    std::exit(ret);
}
void check(const std::errc &ec) noexcept
{
    if (ec ==  std::errc::value_too_large)
        report_and_exit(1, "Failed");
}
int main() {
    char buffer[buffer_size];        
    Type val_to_be_converted, result_of_converted_back;

    auto result1 = std::to_chars(buffer, buffer + buffer_size,  val_to_be_converted);
    check(result1.ec);
    *result1.ptr = '\0';

    auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back);
    check(result2.ec);

    assert(val_to_be_converted == result_of_converted_back);
    report_and_exit(0, buffer);
}

हालाँकि यह पूरी तरह से कंपाइलरों द्वारा लागू नहीं किया गया है, लेकिन निश्चित रूप से इसे लागू किया जाएगा।


0

मैं इस अभिजात्य वर्ग को स्टैकऑवरफ्लो में कहीं से भी चोरी करने के लिए स्ट्रीम करने योग्य कुछ भी बदल सकता हूं:

// make_string
class make_string {
public:
  template <typename T>
  make_string& operator<<( T const & val ) {
    buffer_ << val;
    return *this;
  }
  operator std::string() const {
    return buffer_.str();
  }
private:
  std::ostringstream buffer_;
};

और फिर आप इसका उपयोग करते हैं;

string str = make_string() << 6 << 8 << "hello";

काफी निफ्टी!

इसके अलावा, मैं इस फ़ंक्शन का उपयोग किसी भी स्ट्रीम करने योग्य तार को परिवर्तित करने के लिए करता हूं, यदि आप एक नंबर को शामिल नहीं करने वाले स्ट्रिंग को पार्स करने का प्रयास करते हैं, तो यह बहुत सुरक्षित नहीं है; (और यह पिछले एक के रूप में के रूप में चालाक नहीं है)

// parse_string
template <typename RETURN_TYPE, typename STRING_TYPE>
RETURN_TYPE parse_string(const STRING_TYPE& str) {
  std::stringstream buf;
  buf << str;
  RETURN_TYPE val;
  buf >> val;
  return val;
}

इस रूप में उपयोग करें:

int x = parse_string<int>("78");

तुम भी wstrings के लिए संस्करण चाहते हो सकता है।


5
यह वही है जो बढ़ावा देता है :: lexical_cast करता है। और बढ़ावा यह एक अधिक सामान्य आक्रमण में करता है।
अर्मेन त्सिरुयान

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