std :: স্ট্রিং থেকে ভাসা বা দ্বিগুণ


100

আমি রূপান্তর করার চেষ্টা করছি std::stringকরার float/double। আমি চেষ্টা করেছিলাম:

std::string num = "0.6";
double temp = (double)atof(num.c_str());

তবে এটি সর্বদা শূন্য ফিরে আসে। অন্য কোন উপায়ে?


4
এক দশক আগে ইতিমধ্যে উদ্ভূত কোনও কিছুর ওভাররেঞ্জাইনারের উত্সাহ প্রতিরোধ করুন।
হাওয়ে

4
আপনি কি নিশ্চিত যে আপনি এটি সঠিকভাবে আউটপুট করেছেন? এটি শূন্য উপার্জন করা উচিত নয়
জোহানেস স্কাউব -

4
অতিরিক্ত হিসাবে, আপনার atof নিক্ষেপ করার দরকার নেই, এটি ইতিমধ্যে একটি ডাবল ফেরত দেয়।
আলবার্তোপিএল

আমি নিশ্চিত. ডিবাগার আমাকে 0. দেখায় এবং ফলাফল 0 হয় প্ল্যাটফর্ম: লিনাক্স।
সর্বোচ্চ ফ্রেই

13
আপনি কি সঠিক লোকেল ইনস্টল করেছেন তা নিশ্চিত? "0,6" বা সেটলোকেলে (LC_NUMERIC, "C") চেষ্টা করুন;
জোহানেস স্কাউব - লিটব

উত্তর:


126
std::string num = "0.6";
double temp = ::atof(num.c_str());

এটি আমার জন্য, এটি একটি বৈধ সি ++ সিনট্যাক্সটি একটি স্ট্রিংকে ডাবলে রূপান্তর করা।

আপনি এটি স্ট্রিংস্ট্রিম বা বুস্ট :: লেক্সিক্যাল_কাস্ট দিয়ে করতে পারেন তবে এগুলি পারফরম্যান্স পেনাল্টি নিয়ে আসে।


আহা তোমার কিউটি প্রকল্প আছে ...

QString winOpacity("0.6");
double temp = winOpacity.toDouble();

অতিরিক্ত নোট:
ইনপুট ডেটা একটি হয়, তাহলে const char*, QByteArray::toDoubleদ্রুততর হবে।


7
বুস্ট :: লেক্সিক্যাল_কাস্ট স্ট্রিম করছে।
টিমডাব্লু

4
আমি মনে করি তারা সাধারণত পারফরম্যান্স পেনাল্টি নিয়ে বলতে পারে না। আপনার যখন একটি চীন >> নাম; এর ঠিক আগে কী ঘটেছিল সে সম্পর্কে ভাবুন; মিলিসেকেন্ডস লেক্সিক্যাল_কাস্টটি ধীর গতিতে খেয়াল করতে ব্যবহারকারীর খুব দ্রুত (রোল জন স্কিটের মতো) টাইপ করতে হবে :) এটি বলেছে, আমি বিশ্বাস করি যে এমন কিছু কাজ রয়েছে যেখানে লেজিক্যাল_কাস্ট খুব বেশি পারফরম্যান্স সাফল্য অর্জন করে :)
জোহানেস স্কাউব - লিটব

4
এই সমাধানের জন্য, atof () এর সামনে :: কী করবে? সেখানে থাকার দরকার কী?
শিববধু

4
@ শ্যাখ্রিঃ কারণ আমি নিশ্চিত করতে চাই যে আমি বিশ্বব্যাপী নেমস্পেস থেকে atof ফাংশনটি ব্যবহার করব।
টিমডাব্লু

4
বর্তমান
লোকালে

104

স্ট্যান্ডার্ড লাইব্রেরি (সি ++ 11) এর সাথে পছন্দসই কার্যকারিতা সরবরাহ করে std::stod:

std::string  s  = "0.6"
std::wstring ws = "0.7"
double d  = std::stod(s);
double dw = std::stod(ws);

সাধারণত অন্যান্য অন্যান্য মৌলিক ধরণের জন্য, দেখুন <string>। সি স্ট্রিংগুলির জন্য কিছু নতুন বৈশিষ্ট্যও রয়েছে। দেখা<stdlib.h>


4
আমি এই সমাধানটি পছন্দ করি তবে এটি কেবল সি ++ 11 থেকে আসে appears সুতরাং আমার এসডিকে উপলভ্য নয়।
pamplemousse_mk2

এটি জানতে পেরে দুর্দান্ত যে সি ++ স্ট্যান্ডার্ড কমিটি এটি যুক্ত করেছে। ostringstreamনিজেই টাইপ করতে খুব দীর্ঘ ছিল, একা ব্যবহার করা যাক ..
ববোবোবো

4
ফ্লোটগুলির জন্য (যে প্রশ্নটি আমি গুগলের সাথে "সি ++ স্ট্রিং ফ্লোট করতে" টাইপ করে পেয়েছি) হিসাবে জিজ্ঞাসা করা হয়েছে, স্ট্যান্ড :: স্টোফ ব্যবহার করা উচিত।
Étienne

4
কেবলমাত্র একটি নোট এটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে: এসটিডি :: অবৈধ_আরগমেন্ট (যদি রূপান্তর ব্যর্থ হয়) স্ট্যান্ড :: আউট_ অফ_আরঞ্জ (যদি সীমার বাইরে থাকে)
জেসন ডাউসেট

4
ক্রেতা সাবধান, বর্তমান লোকেলের উপর নির্ভর করে।
এনএমআর

29

লেক্সিকাল castালাই খুব সুন্দর।

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

using std::endl;
using std::cout;
using std::string;
using boost::lexical_cast;

int main() {
    string str = "0.6";
    double dub = lexical_cast<double>(str);
    cout << dub << endl;
}

ধন্যবাদ, এটি কাজ করে .. তবে এটি আমার জন্য একটি প্রশ্ন: আমার কোডটি কেন কাজ করছে না।
সর্বোচ্চ ফ্রেই

4
@ জোহানেস স্কাউব: এডিএল-এর উপর ভিত্তি করে, তিনিও সম্ভবত ব্যবহারের সিদ্ধান্তগুলি ব্যবহার করতে পারেন এবং যা তিনি আসলে ব্যবহার করছেন তা সম্ভবত বিপুল সংখ্যক স্ট্যান্ডার্ড উপাদানকে সুযোগে নিয়ে আসবে। তদুপরি লেজিক্যাল_কাস্টটি অত্যন্ত ধীর গতির, সুতরাং আমার কাছ থেকে কোনও উত্তর নেই।

উত্সাহের একটি দুর্দান্ত বৈশিষ্ট্য :: লেক্সিক্যাল_কাস্ট হ'ল ত্রুটি পরিচালনা। যদি কোনও রূপান্তর ব্যর্থ হয় তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয়:try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }
সেমজান ম্যাসিংগার

আরও সুনির্দিষ্ট catch ( boost::bad_lexical_cast const& err )হওয়ার জন্য, ব্যতিক্রমটি ধরতে ব্যবহার করুন ।
সেমজান ম্যাসিংগার

14

আপনি স্ট্যান্ড স্ট্রিমস্ট্রিম ব্যবহার করতে পারেন:

   #include <sstream>
   #include <string>
   template<typename T>
   T StringToNumber(const std::string& numberAsString)
   {
      T valor;

      std::stringstream stream(numberAsString);
      stream >> valor;
      if (stream.fail()) {
         std::runtime_error e(numberAsString);
         throw e;
      }
      return valor;
   }

ব্যবহার:

double number= StringToNumber<double>("0.6");

আহ, সুতরাং আপনি মনে করেন যে উত্সাহ :: লেক্সিক্যাল_কাস্টের একটি ভয়াবহ ইন্টারফেস রয়েছে, তাই না? স্টেফানবির উত্তর দেখুন! বুস্ট একই কাজ করে।
kirsche40

@ kirsche40 বোস্টের সাথে ইতিমধ্যে নির্ভরতা নেই এমন লোকের পক্ষে একটি ভাল বিকল্প বলে মনে হচ্ছে (বুস্টের সাথে সংযোগ কেবল একটি স্ট্যান্ড :: স্ট্রিংকে সংখ্যায় রূপান্তর করতে কিছুটা ওভারকিল!)
জিন-ফিলিপ জোডোইন

@ জিয়ান-ফিলিপ জোদিউন আমি এখন মুছে ফেলা একটি মন্তব্যে জবাব দিয়েছি, যেখানে কেউ বুস্টের প্রস্তাব দিয়েছেন। আমি জানি যে বুস্ট বেশিরভাগ সময় ওভারকিল হয়। যাইহোক, কিছু সময়ের জন্য এখন বুস্টের ব্যবহার "নতুন" সংকলকগুলির মধ্যে সীমাবদ্ধ। পুরানো প্রকল্পগুলি বুস্ট ব্যবহার করতে পারে না। উদাহরণস্বরূপ ASIO st + :: ঠিকানার মতো সি ++ 11-বৈশিষ্ট্যগুলির উপর ভারী নির্ভর করে যা এটি সি ++ 98 / সি ++ 03 সংকলকগুলির জন্য একেবারে অকেজো করে তোলে। আইএমএইচও, যখন প্রকল্পটি শুরু হয়েছিল তখন পুরানো সংকলক সংস্করণগুলির জন্য নতুন "
মানকৃত

10

হ্যাঁ, একটি লেজিকাল কাস্ট সহ। স্ট্রিংস্ট্রিম এবং << অপারেটর ব্যবহার করুন বা বুস্ট ব্যবহার করুন, তারা ইতিমধ্যে এটি প্রয়োগ করেছে।

আপনার নিজস্ব সংস্করণ দেখতে পারে:

template<typename to, typename from>to lexical_cast(from const &x) {
  std::stringstream os;
  to ret;

  os << x;
  os >> ret;

  return ret;  
}

7

আপনি বুস্ট লেক্সিকাল কাস্ট ব্যবহার করতে পারেন:

#include <boost/lexical_cast.hpp>

string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;

দ্রষ্টব্য: বুস্ট :: লেক্সিক্যাল_কাস্ট ব্যতিক্রম ছুঁড়েছে তাই আপনি যখন অবৈধ মান পাস করেন তখন এটি মোকাবেলা করার জন্য আপনাকে প্রস্তুত হওয়া উচিত, স্ট্রিং ("xxx") পাশ করার চেষ্টা করুন


5

আপনি যদি সমস্ত বৃদ্ধিতে টানতে না চান তবে এর সাথে strtod(3)যান <cstdlib>- এটি ইতিমধ্যে একটি দ্বিগুণ দেয়।

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>

using namespace std;

int main()  {
    std::string  num = "0.6";
    double temp = ::strtod(num.c_str(), 0);

    cout << num << " " << temp << endl;
    return 0;
}

ফলাফল:

$ g++ -o s s.cc
$ ./s
0.6 0.6
$

কেন atof () কাজ করে না ... আপনি কোন প্ল্যাটফর্ম / সংকলক চালু আছেন?


স্ট্রিংস্ট্রিম ব্যবহারের জন্য বুস্টের দরকার পড়বে না
জাল্ফ

আপনার পদ্ধতিটিও শূন্য ফিরে আসে। লিনাক্স।
ম্যাক্স ফ্রেই

3

লিনাক্সেও আমার একই সমস্যা ছিল

double s2f(string str)
{
 istringstream buffer(str);
 double temp;
 buffer >> temp;
 return temp;
}

এটা কাজ করে।


2
   double myAtof ( string &num){
      double tmp;
      sscanf ( num.c_str(), "%lf" , &tmp);
      return tmp;
   }

4
অবৈধ উত্তর, আপনি কীভাবে জানবেন যে সংখ্যায় সঞ্চিত মানটি একটি বৈধ ভাসমান পয়েন্ট সংখ্যা? আপনি রিটার্নের ধরণের স্কানফ পরীক্ষা করে দেখুন না, এমএস কোডিং শৈলীর মতো মনে হচ্ছে।

1

এই উত্তরটি আপনার মন্তব্যে লিটবকে ব্যাক আপ করছে। আপনি কেবল ফলাফলটি সঠিকভাবে প্রদর্শন করছেন না এমন আমার গভীর সন্দেহ রয়েছে।

আমার সাথে ঠিক একই ঘটনা ঘটেছিল। আমি কেন একটি 64৪-বিট ইন্টিতে খারাপ মান পাচ্ছি তা আবিষ্কার করার জন্য আমি একটি পুরো দিন ব্যয় করেছি, কেবল এটি আবিষ্কার করতে যে প্রিন্টফ দ্বিতীয় বাইটটিকে উপেক্ষা করছে। আপনি প্রিন্টফের মতো এটির মতো কোনও 64-বিট মানটি পাস করতে পারবেন না।


আমি ফলাফলগুলি দেখতে প্রিন্টফ ব্যবহার করছি না ... এবং আমি সেই মানটি উইন্ডোটির অস্বচ্ছতা সেট করতে ব্যবহার করি এবং আমার উইন্ডোটি সম্পূর্ণ স্বচ্ছ, সুতরাং মান 0 হয়
ম্যাক্স ফ্রেই

1

সি ++ 11 টি উপায় হল std :: stod এবং std :: to_string ব্যবহার করা। দুজনেই ভিজ্যুয়াল স্টুডিও 11 এ কাজ করে।


1

atof()আসল প্রশ্নে কেন কাজ করছেন না: এটিকে দ্বিগুণ করে দেওয়ার বিষয়টি আমাকে সন্দেহজনক করে তুলেছে। কোডটি ছাড়াই সংকলন করা উচিত নয় #include <stdlib.h>, তবে যদি একটি সংকলন সতর্কতা সমাধান করতে কাস্ট যুক্ত করা হয় তবে atof()সঠিকভাবে ঘোষণা করা হয় না। যদি atof()সংকলকটি কোনও int প্রদান করে, umesালাই এটি রূপান্তরকরণের সতর্কবার্তাটি সমাধান করবে, তবে এটি ফেরতের মানটিকে দ্বিগুণ হিসাবে স্বীকৃতি দেবে না

#include <stdlib.h>
#include <string>

... 
  std::string num = "0.6";
  double temp = atof(num.c_str());

সতর্কতা ছাড়াই কাজ করা উচিত।


0

বুস্টকে সমীকরণে টেনে আনার পরিবর্তে আপনি আপনার স্ট্রিংটিকে (অস্থায়ীভাবে) char[]ব্যবহার এবং ব্যবহার হিসাবে রাখতে পারেন sprintf()

তবে অবশ্যই আপনি যেভাবেই বুস্ট ব্যবহার করছেন, এটি আসলে খুব বেশি সমস্যা নয়।


0

আপনি স্ট্রিংয়ের জন্য বুস্ট লেজিক্যাল_কাস্ট চান না <-> যাইহোক ফ্লোটিং পয়েন্ট। ব্যবহারের ক্ষেত্রে এই উপসেটটি একমাত্র সেট যার জন্য ধারাবাহিকভাবে বুস্ট করা পুরানো ফাংশনগুলির চেয়ে খারাপ-এবং তারা মূলত সেখানে তাদের সমস্ত ব্যর্থতা কেন্দ্রীভূত করেছিল, কারণ তাদের নিজস্ব কার্যকারিতার ফলাফলগুলি এই জাতীয় রূপান্তরগুলির জন্য স্ক্যানফ এবং প্রিন্টফ ব্যবহার করার চেয়ে 20-25X স্লুওয়ার পারফরম্যান্স দেখায়।

গুগল এটি নিজে। বুস্ট :: লেক্সিক্যাল_কাস্ট 50 টি রূপান্তর এর মতো কিছু পরিচালনা করতে পারে এবং যদি আপনি ভাসমান পয়েন্টের সাথে যুক্তগুলি বাদ দেন তবে এটি সুস্পষ্ট বিকল্পগুলির মতো ভাল বা আরও ভাল (সেই সমস্ত ক্রিয়াকলাপের জন্য একটি একক এপিআই থাকার অতিরিক্ত সুবিধা সহ)। পারফরম্যান্সের দিক থেকে টাইটানিকের মতো আইসবার্গে আঘাত করা ভাসমান এবং এটি নিয়ে আসা।

পুরানো, ডেডিকেটেড স্ট্র-> ডাবল ফাংশনগুলি 30 এমএস (বা আরও ভাল) এর মতো 10000 পার্স করতে পারে। লেক্সিক্যাল_কাস্ট একই কাজ করতে 650 এমএসের মতো কিছু লাগে।


কোন উত্স নেই? আমি এটি নিজেই গুগল
ব্লেক

0

আমার সমস্যা:

  1. লোকেল স্বতন্ত্র স্ট্রিং দ্বিগুণ (সর্বদা দশমিক বিভাজক '।')
  2. স্ট্রিং রূপান্তর ব্যর্থ হলে ত্রুটি সনাক্তকরণ

আমার সমাধান (উইন্ডোজ ফাংশন _wcstod_l ব্যবহার করে):

// string to convert. Note: decimal seperator is ',' here
std::wstring str = L"1,101";

// Use this for error detection
wchar_t* stopString;

// Create a locale for "C". Thus a '.' is expected as decimal separator
double dbl = _wcstod_l(str.c_str(), &stopString, _create_locale(LC_ALL, "C")); 

if (wcslen(stopString) != 0)
{
    // ... error handling ... we'll run into this because of the separator
}

এইচটিএইচ ... আমাকে এই সমাধানটি পেতে বেশ দীর্ঘ সময় নিয়েছে। এবং আমার এখনও অনুভূতি রয়েছে যে স্ট্রিং স্থানীয়করণ এবং স্টাফ সম্পর্কে আমি যথেষ্ট পরিমাণে জানি না ...

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