কোনও সংখ্যাকে স্ট্রিংয়ে রূপান্তর করতে এবং সি ++ এর বিপরীতে


120

যেহেতু এই প্রশ্নটি প্রতি সপ্তাহে জিজ্ঞাসা করা হয়, এই FAQ ব্যবহারকারীদের প্রচুর সাহায্য করতে পারে।

  • কিভাবে পূর্ণসংখ্যা সি ++ এ স্ট্রিংয়ে রূপান্তর করতে হয়

  • কীভাবে স্ট্রিংটিকে সি ++ তে পূর্ণসংখ্যায় রূপান্তর করা যায়

  • কীভাবে ফ্লোটিং-পয়েন্ট নম্বরটিকে সি ++ তে স্ট্রিংয়ে রূপান্তর করতে হয়

  • কীভাবে একটি স্ট্রিংকে সি ++ এ ভাসমান-পয়েন্ট সংখ্যাতে রূপান্তর করতে হবে


এগুলির মত রূপান্তর করার জন্য, আমার কাছে বুকমার্ক কনভার্টাইপস
ডট

উত্তর:


129

সি ++ 11 এর জন্য আপডেট

C++11স্ট্যান্ডার্ড হিসাবে , স্ট্রিং-থেকে-নম্বর রূপান্তর এবং তদ্বিপরীত স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্নির্মিত। নিম্নলিখিত 21 <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 এর স্ট্রিং প্রদান করে। এটি এই ফাংশনগুলি ব্যবহার করে ট্রিপ ফ্লোটিং পয়েন্টের মানগুলি অসম্ভব করে তোলে।
জিমি

@ মজা 4 জিমি এটি কি স্ট্যান্ডার্ড বা বাস্তবায়ন দ্বারা নির্দিষ্ট একটি বিধিনিষেধ? উত্তরে যুক্ত করবে। রাউন্ড-ট্রিপিংগুলি স্ট্রিংগুলির মাধ্যমে ভেসে ওঠে না এটি কোনও ভাল ধারণা।
কিলিয়ানডিএস

সি ++ মান বলে " রিটার্নস: প্রতিটি ফাংশন একটি স্ট্রিং বস্তুর যে কল করে উত্পন্ন করা হবে তার যুক্তি মূল্য চরিত্র উপস্থাপনা অধিষ্ঠিত ফেরৎ sprintf(buf, fmt, val)একটি বিন্যাসে সুনির্দিষ্টভাবে উল্লেখ করা সঙ্গে "% D " , "% U " , "% LD " , " যথাক্রমে % lu " , "% lld " , "% llu " , "% f " , "% f " , বা "% Lf " , যেখানে bufপর্যাপ্ত আকারের একটি অভ্যন্তরীণ অক্ষর বাফারকে নির্ধারণ করে I" C99 এ আমার নজর ছিল জন্য আদর্শ printf, এবং আমি মনে করি যে দশমিক স্থান সংখ্যা উপর নির্ভরশীল #define DECIMAL_DIGমধ্যেভাসা
fun4jimmy

ব্রুস ডসনের নিজের ব্লগে রাউন্ড ট্রিপিং ফ্লোটিং পয়েন্ট নম্বরগুলির জন্য কী নির্ভুলতা প্রয়োজন তা নিয়ে কিছু ভাল নিবন্ধ রয়েছে ।
fun4jimmy

2
এই সমস্ত ফাংশনগুলি বিশ্বব্যাপী স্থানীয় দ্বারা প্রভাবিত হয়, যা আপনি লাইব্রেরিগুলি ব্যবহার করে এবং বিশেষত থ্রেড ব্যবহার করা হলে সমস্যার কারণ হতে পারে। : আমার প্রশ্ন এখানে দেখুন stackoverflow.com/questions/31977457/...
Ident

86

কীভাবে সি ++ 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. বুস্ট লেক্সিকাল কাস্ট ব্যবহার করুন । আপনি যদি বুস্টের সাথে পরিচিত না হন তবে এই লেক্সিক্যাল_কাস্টের মতো একটি ছোট লাইব্রেরি দিয়ে শুরু করা ভাল ধারণা। বুস্ট এবং এটির ডকুমেন্টেশনগুলি ডাউনলোড এবং ইনস্টল করতে এখানে যান । যদিও বুস্ট সি ++ স্ট্যান্ডার্ডে নেই বুস্টের অনেকগুলি লাইব্রেরি শেষ পর্যন্ত মানকীকৃত হয় এবং বুস্টকে সেরা সি ++ গ্রন্থাগারগুলি হিসাবে ব্যাপকভাবে বিবেচনা করা হয়।

    লেক্সিকাল কাস্টটি নীচের স্ট্রিমগুলি ব্যবহার করে, সুতরাং মূলত এই বিকল্পটি আগেরটির মতো, কেবল কম ভার্বোস।

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

কিভাবে একটি স্ট্রিং সি ++ 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, যা আমি সি ++ 03 বা সি 89 এর মধ্যে খুঁজে পাই না। অবিশ্বস্ত / যাচাই না করা ইনপুটগুলির জন্য, বা স্ট্রিমগুলি সমর্থন করে না এমন বেসগুলিতে কাজ করার সময় আপনার প্রয়োজন হয় strtol, যা ত্রুটি আচরণের সংজ্ঞা দিয়েছে। এবং atof/ এর জন্য অনুরূপ মন্তব্য strtod
স্টিভ জেসোপ

2
cplusplus.com "atoi" সম্পর্কে ভুল। এটি প্রত্যাবর্তন মান সম্পর্কে বলে "যদি কোনও বৈধ রূপান্তর সম্পাদন করা যায় না, একটি শূন্য মান ফিরে পাওয়া যায় If ফলাফলের মান উপস্থাপন করা যায় না, আচরণটি হ'ল e এবং এটি "ত্রুটিযুক্ত আচরণ ব্যতীত এগুলি সমতুল্য (int)strtol(nptr, (char **)NULL, 10)at এটুই [...] ফাংশনগুলি রূপান্তরিত মানটি ফিরিয়ে দেয়" " সিপিএলস্প্লস.কম নতুনদের জন্য তথ্যের অবিশ্বাস্য খারাপ উত্স হিসাবে পরিচিত।
জোহানেস স্কাউব -

istr >> i1 >> f >> i2;সাফল্যের জন্য চেকটি খারাপভাবে মিস করে।
এসবিআই

4
যোগ করতে চানstd::to_string
পাবি

1
@ আর্মেনসিরুনিয়ান: আমার প্রান্ত থেকে +১০, আমি এর মধ্যে যে উত্তর খুঁজে পেয়েছি তার মধ্যে অন্যতম সেরা উত্তর too আপনার উত্তরের জন্য ধন্যবাদ.
অভিনিত

4

সি ++ ১ In- এ, শিরোনামের চারকনভে নতুন স্ট্যান্ডার্ড স্ট্যান্ড :: টু-চার্স এবং স্টাড :: থেকে_চার্স চালু করা হয়েছে ।

std :: to_chars স্থানীয় - স্বতন্ত্র, বরাদ্দ না করে এবং নিক্ষেপ করা হয় না।

অন্যান্য লাইব্রেরি দ্বারা ব্যবহৃত বিন্যাস নীতিগুলির একটি সামান্য উপসেট সরবরাহ করা হয়েছে (যেমন স্ট্যান্ড :: স্প্রিন্টফ)।

থেকে এসটিডি :: to_chars জন্য একই এসটিডি :: from_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");

আপনি রাইটিংয়ের জন্য সংস্করণও পেতে পারেন।


5
এটি ঠিক বুস্ট :: লেক্সিক্যাল_কাস্ট করে। এবং বুস্ট এটি আরও জেনেরিক ফেশে করে।
আর্মেন ​​সিরুনিয়ান

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