मैं एक std :: string को int में कैसे बदल सकता हूँ?


484

बस एक त्वरित प्रश्न है। मैंने इंटरनेट पर बहुत कम देखा है और मुझे कुछ समाधान मिले हैं लेकिन उनमें से किसी ने भी अभी तक काम नहीं किया है। एक स्ट्रिंग को एक इंट में परिवर्तित करने को देखते हुए और मेरा मतलब ASCII कोड नहीं है।

एक त्वरित रन-डाउन के लिए, हम एक स्ट्रिंग के रूप में एक समीकरण में पारित हो जाते हैं। हमें इसे तोड़ना होगा, इसे सही ढंग से प्रारूपित करना होगा और रैखिक समीकरणों को हल करना होगा। अब, यह कहते हुए कि, मैं एक स्ट्रिंग को एक इंट में बदलने में सक्षम नहीं हूं।

मुझे पता है कि स्ट्रिंग या तो प्रारूप (-5) या (25) आदि में होगी, इसलिए यह निश्चित रूप से एक इंट है। लेकिन हम इसे एक तार से कैसे निकालेंगे?

जिस तरह से मैं सोच रहा था कि स्ट्रिंग के माध्यम से एक / के लिए लूप चल रहा है, एक अंक की जांच करें, उसके बाद सभी अंकों को निकालें और फिर देखें कि क्या कोई अग्रणी '-' था, अगर वहाँ है, तो int को गुणा करें - 1।

यह हालांकि इस तरह की एक छोटी सी समस्या के लिए थोड़ा जटिल है। कोई विचार?


9
क्या आपने कोशिश की है atoi()?
I_am_jorf



7
@ क्या आप यह सलाह दे रहे हैं कि वह किसी भी तरह से मानक पुस्तकालयों के साथ भाषा के लिए पूरी लाइब्रेरी का उपयोग कर सकता है?
Bojangles

6
@ ब्रैंडन, अगर आपके पास कोई है std::string myString, और उपयोग करना चाहते हैं atoi, तो आप कहना चाहते हैं atoi(myString.c_str())
रोबो

जवाबों:


726

C ++ 11 में कुछ अच्छे नए रूपांतरित कार्य हैं std::string एक नंबर प्रकार ।

इसलिए इसके बजाय

atoi( str.c_str() )

आप उपयोग कर सकते हैं

std::stoi( str )

strआपका नंबर कहाँ हैstd::string

संख्या के सभी जायके के लिए संस्करण हैं: long stol(string), float stof(string), double stod(string), ... देखना http://en.cppreference.com/w/cpp/string/basic_string/stol


5
Std के मुद्दों के लिए :: stoi see stackoverflow.com/a/6154614/195527 : यह "11x"पूर्णांक में परिवर्तित हो जाएगा 11
सी.सी.

5
#include <stdlib.h> / * atoi * /
उलद कासच

4
@CC यह भी एटॉई का व्यवहार है: cplusplus.com/reference/cstdlib/atoi "स्ट्रिंग में अभिन्न संख्या बनाने वाले लोगों के बाद अतिरिक्त वर्ण हो सकते हैं, जिन्हें अनदेखा किया जाता है और इस फ़ंक्शन के व्यवहार पर कोई प्रभाव नहीं पड़ता है।"
टिन जादूगर

4
क्या आप इस जवाब from_charsको C ++ 17 से अपडेट करना चाहेंगे ? इसे परिमाण की तुलना में अधिक तेज़ गति का आदेश माना जाता है stoi
नाथनऑलिवर


57
std::istringstream ss(thestring);
ss >> thevalue;

पूरी तरह से सही होने के लिए आप त्रुटि झंडे की जांच करना चाहेंगे।


2
यह अलग नहीं होगा -5से (-5)
नवाज

@ नवाज, क्या वास्तव में वहां परिनियन्स हैं, या यह कि ओपी अपने तार कैसे पेश कर रहा है?
विंस्टन Ewert

मुझे नहीं पता। मैं सिर्फ दृष्टिकोण की सीमा को इंगित कर रहा हूं।
नवाज़

16
@ नवाज़, यह "WERWER" इनपुट पर भी काम नहीं कर सकता। मुझे नहीं लगता कि वास्तव में पराग उसके वास्तविक तार का हिस्सा हैं और मुझे नहीं लगता कि इस तथ्य के बारे में मुझे पता नहीं है कि वे प्रासंगिक हैं।
विंस्टन एवर्ट

4
@ नवाज़, ठीक है ... मैं इस तरह से शब्द नहीं लेता, लेकिन मैं देखता हूं कि आप कैसे हो सकते हैं।
विंस्टन इवर्ट

44

संभावित विकल्प नीचे वर्णित हैं:

1. पहला विकल्प: sscanf ()

    #include <cstdio>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        if(sscanf(str.c_str(), "%d", &i) != 1)
            // error management

        // string -> float
        if(sscanf(str.c_str(), "%f", &f) != 1)
            // error management

        // string -> double 
        if(sscanf(str.c_str(), "%lf", &d) != 1)
            // error management

यह एक त्रुटि है (यह भी cppcheck द्वारा दिखाया गया है) क्योंकि "फ़ील्ड चौड़ाई सीमाओं के बिना स्कैनफैक libc के कुछ संस्करणों पर भारी इनपुट डेटा के साथ क्रैश हो सकता है" ( यहां , और यहां देखें )।

2. दूसरा विकल्प: std :: sto * ()

    #include <iostream>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        try {
            // string -> integer
            int i = std::stoi(str);

            // string -> float
            float f = std::stof(str);

            // string -> double 
            double d = std::stod(str);
        } catch (...) {
            // error management
        }   

यह समाधान छोटा और सुरुचिपूर्ण है, लेकिन यह केवल C ++ 11 अनुरूप कंपाइलर पर उपलब्ध है।

3. तीसरा विकल्प: sstreams

    #include <string>
    #include <sstream>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        std::istringstream ( str ) >> i;

        // string -> float
        std::istringstream ( str ) >> f;

        // string -> double 
        std::istringstream ( str ) >> d;

        // error management ??

हालांकि, इस समाधान के साथ खराब इनपुट के बीच अंतर करना मुश्किल है (देखें यहां ) के ।

4. चौथा विकल्प: बूस्ट का लेक्सिकल_कास्ट

    #include <boost/lexical_cast.hpp>
    #include <string>

        std::string str;

        try {
            int i = boost::lexical_cast<int>( str.c_str());
            float f = boost::lexical_cast<int>( str.c_str());
            double d = boost::lexical_cast<int>( str.c_str());
            } catch( boost::bad_lexical_cast const& ) {
                // Error management
        }

हालाँकि, यह सिर्फ एक आवरण है sstream, और प्रलेखन sstreamबेहतर त्रुटि प्रबंधन के लिए उपयोग करने का सुझाव देता है ( यहाँ देखें )।

5. पांचवा विकल्प: स्ट्रेटो * ()

यह समाधान त्रुटि प्रबंधन के कारण बहुत लंबा है, और यह यहां वर्णित है। चूंकि कोई फ़ंक्शन एक सादे इंट नहीं देता है, पूर्णांक के मामले में रूपांतरण की आवश्यकता होती है ( यह रूपांतरण कैसे प्राप्त किया जा सकता है इसके लिए यहां देखें )।

6. छठा विकल्प: Qt

    #include <QString>
    #include <string>

        bool ok;
        std::string;

        int i = QString::fromStdString(str).toInt(&ok);
        if (!ok)
            // Error management

        float f = QString::fromStdString(str).toFloat(&ok);
        if (!ok)
            // Error management 

        double d = QString::fromStdString(str).toDouble(&ok);
        if (!ok)
    // Error management     

निष्कर्ष

सारांश, सबसे अच्छा समाधान C ++ 11 std::stoi()या, एक दूसरे विकल्प के रूप में, क्यूटी पुस्तकालयों का उपयोग है। अन्य सभी समाधान हतोत्साहित या छोटी गाड़ी हैं।


फिक्स्ड। रिपोर्टिंग के लिए धन्यवाद।
क्लाउडियो

सुंदर सारांश, बहुत धन्यवाद। क्या मैं अंतिम समाधान का सुझाव देते हुए प्रारंभिक टिप्पणी जोड़ने का सुझाव दे सकता हूं ताकि केवल विवरण में रुचि रखने वाले लोग पढ़ते रहें?
लूका

1
यह स्वीकृत उत्तर होना चाहिए, यह भी कि आप भूल गए (या इसके कारण जोड़ना चाहिए क्योंकि यह एक पुराना उत्तर है) from_chars
xception

40

स्ट्रिंग को पूर्णांक में बदलने के लिए एटोई फ़ंक्शन का उपयोग करें:

string a = "25";

int b = atoi(a.c_str());

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/


14
कभी भी उपयोग न करें atoistrtolसब कुछ atoiकरता है, लेकिन बेहतर है, और सुरक्षित रूप से विफल रहता है।
बेन Voigt

9

Boost.Lexical_cast के बारे में क्या ?

यहाँ उनका उदाहरण दिया गया है:

निम्नलिखित उदाहरण संख्यात्मक डेटा के अनुक्रम के रूप में कमांड लाइन तर्कों को मानते हैं:

int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}

लिंक टूट गया है। क्या आप इसे ठीक कर सकते हैं?
युकेन झोंग

5

बेशक, मेरा समाधान नकारात्मक पूर्णांकों के लिए काम नहीं करेगा, लेकिन यह सभी सकारात्मक पूर्णांकों को पूर्णांक से युक्त इनपुट पाठ से निकालेगा। यह numeric_onlyलोकेल का उपयोग करता है :

int main() {
        int num;
        std::cin.imbue(std::locale(std::locale(), new numeric_only()));
        while ( std::cin >> num)
             std::cout << num << std::endl;
        return 0;
}

इनपुट टेक्स्ट:

 the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878

आउटपुट पूर्णांक:

 5
25
7987
78
9878

वर्ग numeric_onlyके रूप में परिभाषित किया गया है:

struct numeric_only: std::ctype<char> 
{
    numeric_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
        return &rc[0];
    }
};

पूरा ऑनलाइन डेमो: http://ideone.com/dRWSj


4

यह शायद ओवरकिल का एक सा है, लेकिन boost::lexical_cast<int>( theString )काफी अच्छी तरह से काम करना चाहिए।


एक लेखन त्रुटि। यह बस होना चाहिए boost::lexical_cast<int>( theString )(जहां theStringचर का नाम है जिसमें वह स्ट्रिंग है जिसे आप बदलना चाहते हैं int)।
जेम्स कंज

1

atoi एक अंतर्निहित फ़ंक्शन है जो स्ट्रिंग को पूर्णांक में परिवर्तित करता है, यह मानते हुए कि स्ट्रिंग पूर्णांक प्रतिनिधित्व के साथ शुरू होता है।

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/


किसी भी समय आप के बारे में सोचते हैं atoi, strtolइसके बजाय का उपयोग करें ।
बेन Voigt

1

Windows में, आप उपयोग कर सकते हैं:

const std::wstring hex = L"0x13";
const std::wstring dec = L"19";

int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
    std::cout << ret << "\n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
    std::cout << ret << "\n";
}

strtol, stringstreamअगर आप hexdecimal व्याख्या करने के लिए की जरूरत आधार निर्दिष्ट करने के लिए की जरूरत है।


1

खैर, बहुत सारे जवाब, बहुत सारी संभावनाएं। यहाँ मुझे जो याद आ रहा है वह कुछ सार्वभौमिक विधि है जो एक स्ट्रिंग को अलग-अलग C ++ अभिन्न प्रकार (लघु, int, long, bool, ...) में परिवर्तित करती है। मैं निम्नलिखित समाधान के साथ आया:

#include<sstream>
#include<exception>
#include<string>
#include<type_traits>

using namespace std;

template<typename T>
T toIntegralType(const string &str) {
    static_assert(is_integral<T>::value, "Integral type required.");
    T ret;
    stringstream ss(str);
    ss >> ret;
    if ( to_string(ret) != str)
        throw invalid_argument("Can't convert " + str);
    return ret;
}

यहाँ उपयोग के उदाहरण हैं:

string str = "123";
int x = toIntegralType<int>(str); // x = 123

str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int

str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception

एक स्ट्रिंग को एक अभिन्न प्रकार में बदलने के लिए केवल स्ट्रैस्टस्ट आउटपुट ऑपरेटर का उपयोग क्यों नहीं किया जाता है? यहाँ उत्तर है: मान लीजिए कि एक स्ट्रिंग में एक मान है जो इच्छित अभिन्न प्रकार के लिए सीमा से अधिक है। एग्जाम के लिए, वंडोज़ पर 64 अधिकतम इंट 2147483647 है। आइए स्ट्रिंग को एक मान अधिकतम इंट 1 + स्ट्रिंग स्ट्रिंग = "2147483648" पर असाइन करें। अब, जब स्ट्रिंग को एक इंट में परिवर्तित करना है:

stringstream ss(str);
int x;
ss >> x;

x 2147483647 हो जाता है, जो निश्चित रूप से एक त्रुटि है: स्ट्रिंग "2147483648" को 2147483647 int में परिवर्तित नहीं किया जाना चाहिए था। प्रदान की गई फ़ंक्शन इस तरह की त्रुटियों को फेंक देती है और अपवाद फेंक देती है।


0

से http://www.cplusplus.com/reference/string/stoi/

// stoi example
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoi

int main ()
{
  std::string str_dec = "2001, A Space Odyssey";
  std::string str_hex = "40c3";
  std::string str_bin = "-10010110001";
  std::string str_auto = "0x7f";

  std::string::size_type sz;   // alias of size_t

  int i_dec = std::stoi (str_dec,&sz);
  int i_hex = std::stoi (str_hex,nullptr,16);
  int i_bin = std::stoi (str_bin,nullptr,2);
  int i_auto = std::stoi (str_auto,nullptr,0);

  std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";
  std::cout << str_hex << ": " << i_hex << '\n';
  std::cout << str_bin << ": " << i_bin << '\n';
  std::cout << str_auto << ": " << i_auto << '\n';

  return 0;
}

आउटपुट:

2001, ए स्पेस ओडिसी: 2001 और [, ए स्पेस ओडिसी]

40 सी 3: 16579

-10010110001: -1201

0x7f: 127



0
ll toll(string a){
    ll ret=0;
    bool minus=false;
    for(auto i:a){
        if(i=='-'){ minus=true; continue; }
        ret*=10;
        ret+=(i-'0');
    } if(minus) ret*=-1;
    return ret;
    # ll is defined as, #define ll long long int
    # usage: ll a = toll(string("-1234"));
}

0

स्ट्रिंग प्रतिनिधित्व से पूर्णांक मान में बदलने के लिए, हम std :: stringstream का उपयोग कर सकते हैं।

यदि कनवर्ट किया गया मान पूर्णांक डेटा प्रकार के लिए सीमा से बाहर है, तो यह INT_MIN या INT_MAX लौटाता है।

इसके अलावा अगर स्ट्रिंग वैल्यू को एक वैध इंट डेटा प्रकार के रूप में नहीं दिखाया जा सकता है, तो 0 लौटा दिया जाता है।

#include 
#include 
#include 

int main() {

    std::string x = "50";
    int y;
    std::istringstream(x) >> y;
    std::cout << y << '\n';
    return 0;
}

आउटपुट: 50

उपरोक्त आउटपुट के अनुसार, हम इसे स्ट्रिंग संख्याओं से पूर्णांक संख्या में परिवर्तित कर सकते हैं।

स्रोत और स्ट्रिंग में int c ++ के लिए अधिक


-2

एक पंक्ति संस्करण: long n = strtol(s.c_str(), NULL, base); :।

( sस्ट्रिंग है, और baseएक intतरह के रूप में 2, 8, 10, 16)

आप अधिक जानकारी के लिए इस लिंक का उल्लेख कर सकते हैं strtol


मुख्य विचार strtolफ़ंक्शन का उपयोग करना है, जिसमें शामिल है cstdlib

चूंकि strtolकेवल charसरणी के साथ संभालता है , हमें सरणी में बदलने stringकी charआवश्यकता है। आप इस लिंक को देख सकते हैं ।

एक उदाहरण:

#include <iostream>
#include <string>   // string type
#include <bitset>   // bitset type used in the output

int main(){
    s = "1111000001011010";
    long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string

    cout << s << endl;
    cout << t << endl;
    cout << hex << t << endl;
    cout << bitset<16> (t) << endl;

    return 0;
}

जो उत्पादन करेगा:

1111000001011010
61530
f05a
1111000001011010

-3

एक और आसान तरीका है: मान लीजिए कि आपके पास एक चरित्र है c='4' कि आप इन चरणों में से एक कर सकते हैं:

पहला: int q

q=(int) c ; (q is now 52 in ascii table ) . q=q-48; remember that adding 48 to digits is their ascii code .

दूसरा तरीका:

q=c-'0'; the same , character '0' means 48


1
सवाल से परिवर्तित के बारे में है stringके लिए intके बजाय से charकरने के लिए string
युकेन झोंग

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