আমি কীভাবে একটি এসটিডি :: স্ট্রিংকে ইনটে রূপান্তর করতে পারি?


483

শুধু একটি দ্রুত প্রশ্ন আছে। আমি ইন্টারনেটের চারপাশে বেশ খানিকটা নজর রেখেছি এবং আমি কয়েকটি সমাধান পেয়েছি তবে তাদের কোনওটি এখনও কাজ করেনি। কোনও স্ট্রিংকে একটি ইনটে রূপান্তর করা এবং আমার অর্থ এএসসিআইআই কোড নয়।

দ্রুত রান ডাউন করার জন্য, আমরা একটি স্ট্রিং হিসাবে সমীকরণে পাস করা হয়। আমরা এটিকে ভেঙে ফেলা, সঠিকভাবে ফর্ম্যাট করা এবং রৈখিক সমীকরণগুলি সমাধান করতে হবে। এখন, এই কথাটি বলে, আমি কোনও স্ট্রিংকে কোন ইনটে রূপান্তর করতে পারছি না।

আমি জানি যে স্ট্রিংটি (-5) বা (25) ইত্যাদি বিন্যাসে থাকবে তাই এটি অবশ্যই একটি অন্তর্নিহিত। কিন্তু আমরা কীভাবে স্ট্রিং থেকে এটি নিষ্কাশন করব?

আমি যেভাবে ভাবছিলাম সেই স্ট্রিংটি দিয়ে / চলার সময় লুপ চালাচ্ছি, একটি সংখ্যার জন্য পরীক্ষা করুন, তার পরে সমস্ত অঙ্কগুলি বের করুন এবং তারপরে কোনও শীর্ষস্থানীয় আছে কিনা তা দেখুন '-' যদি থাকে, তবে পূর্বে সংখ্যাটি গুণান - 1।

যদিও এইরকম ছোট সমস্যাটির জন্য এটি কিছুটা জটিল seems কোন ধারনা?


9
আপনি চেষ্টা করেছেন atoi()?
i_am_jorf



7
@ চ্যাড তাই আপনি সুপারিশ করছেন যে ভাষা স্ট্যান্ডার্ড লাইব্রেরিগুলির সাথে ভাষা যেভাবেই করা যায় তার জন্য একটি পুরো লাইব্রেরি ব্যবহার করবেন?
বোজ্যাঙ্গলেস

6
@ ব্র্যান্ডন, আপনার যদি একটি থাকে std::string myStringএবং ব্যবহার atoiকরতে চান তবে আপনি বলতে চান atoi(myString.c_str())
রোব

উত্তর:


725

সি ++ 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
এসটিডি :: stoi দেখুন সঙ্গে সমস্যার জন্য stackoverflow.com/a/6154614/195527 : এটা রূপান্তর করবে "11x"পূর্ণসংখ্যা 11
সিসি।

5
# অন্তর্ভুক্ত <stdlib.h> / * আতই * /
উলাদ কাসাচ

4
@ সিসি এটি আটোয়ার আচরণও করে: cplusplus.com/references/cstdlib/atoi "স্ট্রিংটিতে অবিচ্ছেদ্য সংখ্যা গঠনের পরে অতিরিক্ত অক্ষর থাকতে পারে, যা এড়ানো হয় এবং এই ফাংশনের আচরণে কোনও প্রভাব ফেলে না।"
টিন উইজার্ড

4
আপনি কি এই উত্তরটি from_charsC ++ 17 দিয়ে আপডেট করবেন ? এটির চেয়ে দ্রুততরতার অর্ডার হওয়ার কথা stoi
নাথান অলিভার

stoiপছন্দ করা উচিত। দেখুন কেন আমি আটাই () ব্যবহার করব না?
ফুক্লভি

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

পুরোপুরি সঠিক হতে আপনি ত্রুটিযুক্ত পতাকাগুলি পরীক্ষা করতে চান।


2
এটি -5থেকে নিষ্কাশন করা হবে না (-5)
নওয়াজ

@ নাওয়াজ, প্যারেনরা কি আসলে সেখানে আছেন, বা ঠিক কীভাবে ওপি তার স্ট্রিং উপস্থাপন করছেন?
উইনস্টন ইওয়ার্ট

আমি জানি না। আমি কেবল পদ্ধতির সীমাবদ্ধতার দিকে ইঙ্গিত করছি।
নওয়াজ

16
@ নাওয়াজ, এটি "ওয়ারওয়ার" ইনপুটটিতেও কাজ করতে পারে না। আমি মনে করি না যে প্যারেনগুলি আসলে তার আসল স্ট্রিংয়ের অংশ এবং আমি মনে করি না যে আমি তাদের পার্স করি না তা প্রাসঙ্গিক।
উইনস্টন ইওয়ার্ট

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

এটি একটি ত্রুটি (সিপিচেক দ্বারাও প্রদর্শিত) কারণ "ক্ষেত্রের প্রস্থের সীমা ছাড়াই স্ক্যানফ libc এর কয়েকটি সংস্করণে বিশাল ইনপুট ডেটা দিয়ে ক্র্যাশ করতে পারে" (দেখুন এখানে এবং এখানে ))

২. দ্বিতীয় বিকল্প: স্ট্যান্ড :: স্টো * ()

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

এই সমাধানটি সংক্ষিপ্ত এবং মার্জিত, তবে এটি কেবল সি ++ 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 ??

তবে এই সমাধানটি দিয়ে খারাপ ইনপুট ( এখানে দেখুন ) এর মধ্যে পার্থক্য করা শক্ত ।

৪. চতুর্থ বিকল্প: বুস্টের লেজিক্যাল_কাস্ট

    #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. পঞ্চম বিকল্প: স্ট্রটো * ()

ত্রুটি পরিচালনার কারণে এই সমাধানটি খুব দীর্ঘ। যেহেতু কোনও ক্রিয়াকলাপ কোনও সরল ইন্টি ফেরায় না তাই পূর্ণসংখ্যার ক্ষেত্রে একটি রূপান্তর প্রয়োজন ( কীভাবে এই রূপান্তরটি অর্জন করা যায় তা এখানে দেখুন )।

Six. ষষ্ঠ বিকল্প: 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     

উপসংহার

সংক্ষেপে, সর্বোত্তম সমাধান হ'ল সি ++ 11 std::stoi()বা দ্বিতীয় বিকল্প হিসাবে কিউটি লাইব্রেরি ব্যবহার। অন্যান্য সমস্ত সমাধান নিরুৎসাহিত বা বগী।


সংশোধন করা হয়েছে। রিপোর্ট করার জন্য ধন্যবাদ।
ক্লাদিও

সুন্দর সংক্ষিপ্তসার, অনেক ধন্যবাদ। চূড়ান্ত সমাধানের পরামর্শ দেওয়ার জন্য আমি কি প্রাথমিক মন্তব্য যুক্ত করার পরামর্শ দিতে পারি যাতে কেবল বিশদে আগ্রহী ব্যক্তিরা পড়া চালিয়ে যান?
লুকা

1
এই গ্রহণযোগ্য উত্তর হওয়া উচিত, এছাড়াও আপনি ভুলে গিয়েছিলেন (বা বরং এটি একটি পুরানো উত্তর যুক্ত করা উচিত) থেকে_চার্স
xception

40

স্ট্রিংটিকে পূর্ণসংখ্যায় রূপান্তর করতে atoi ফাংশনটি ব্যবহার করুন:

string a = "25";

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

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


14
কখনও ব্যবহার করবেন না atoistrtolসবকিছু atoiকরে তবে আরও ভাল হয় এবং নিরাপদে ব্যর্থ হয়।
বেন ভয়েগট

9

বুস্ট.লেক্সিকাল_কাস্ট সম্পর্কে কী ?

এখানে তাদের উদাহরণ:

নিম্নলিখিত উদাহরণটি কমান্ড লাইন আর্গুমেন্টগুলিকে সংখ্যার ডেটার ক্রম হিসাবে বিবেচনা করে:

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পরিবর্তে ব্যবহার করুন।
বেন ভয়েগট

1

উইন্ডোজ, আপনি ব্যবহার করতে পারেন:

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আপনাকে হেক্সডিসিমাল ব্যাখ্যা করার প্রয়োজন হলে বেসটি নির্দিষ্ট করতে হবে।


1

ঠিক আছে, প্রচুর উত্তর, অনেক সম্ভাবনা। আমি এখানে যা অনুপস্থিত তা হ'ল কিছু সর্বজনীন পদ্ধতি যা একটি স্ট্রিংকে বিভিন্ন সি ++ ইন্টিগ্রাল টাইপগুলিতে রূপান্তর করে (সংক্ষিপ্ত, ইনট, লং, বুল, ...)। আমি নিম্নলিখিত সমাধান নিয়ে এসেছি:

#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

স্ট্রিং স্ট্রিম আউটপুট অপারেটরটিকে স্ট্রিংকে একটি অবিচ্ছেদ্য ধরণের রূপান্তর করতে কেন ব্যবহার করবেন না? উত্তরটি এখানে: আসুন একটি স্ট্রিংয়ের মধ্যে এমন একটি মান রয়েছে যা অভিহিত ইন্টিগ্রাল টাইপের সীমা অতিক্রম করে। পরীক্ষার জন্য, উইন্ডোজে max৪ সর্বাধিক ইনট 2147483647। এখন, স্ট্রিংটিকে একটি ইনটে রূপান্তর করার সময়:

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

x 2147483647 হয়ে যায়, যা অবশ্যই একটি ত্রুটি: স্ট্রিং "2147483648" 2147483647 ইন্টিতে রূপান্তরিত হওয়ার কথা ছিল না The


0

Http://www.cplsplus.com/references/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 এবং [, একটি স্পেস ওডিসি]

40c3: 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 :: স্ট্রিংস্ট্রিম ব্যবহার করতে পারি।

যদি রূপান্তরিত মানটি পূর্ণসংখ্যার ডেটা টাইপের জন্য সীমার বাইরে থাকে তবে এটি INT_MIN বা INT_MAX প্রদান করে।

এছাড়াও যদি স্ট্রিং মানটি কোনও বৈধ int ডাটা টাইপ হিসাবে প্রতিনিধিত্ব করতে না পারে তবে 0 প্রদান করে।

#include 
#include 
#include 

int main() {

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

আউটপুট: 50

উপরের আউটপুট অনুযায়ী, আমরা দেখতে পাচ্ছি এটি স্ট্রিং নম্বর থেকে পূর্ণসংখ্যার সাথে রূপান্তরিত।

উত্স এবং স্ট্রিং টু সি ++ এ আরও


-2

এক লাইনের সংস্করণ: long n = strtol(s.c_str(), NULL, base);

( sএটি স্ট্রিং এবং baseএটি int2, 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' তাই আপনি এই পদক্ষেপগুলির একটি করতে পারেন:

1 ম: 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
Yuchen Zhong

বগি এবং প্রশ্নের সাথে মেলে না
Caoanan
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.